NetworkIdentity.java revision 55a442e58262e253df965d652bd8219c8d1e72d3
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright (C) 2011 The Android Open Source Project 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * you may not use this file except in compliance with the License. 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * You may obtain a copy of the License at 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * See the License for the specific language governing permissions and 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * limitations under the License. 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)package android.net; 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import static android.net.ConnectivityManager.TYPE_WIFI; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import static android.net.ConnectivityManager.getNetworkTypeName; 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import static android.net.ConnectivityManager.isNetworkTypeMobile; 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import android.content.Context; 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import android.net.wifi.WifiInfo; 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import android.net.wifi.WifiManager; 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import android.os.Build; 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import android.telephony.TelephonyManager; 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import java.util.Objects; 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/** 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Network definition that includes strong identity. Analogous to combining 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * {@link NetworkInfo} and an IMSI. 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @hide 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)public class NetworkIdentity implements Comparable<NetworkIdentity> { 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /** 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * When enabled, combine all {@link #mSubType} together under 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * {@link #SUBTYPE_COMBINED}. 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public static final boolean COMBINE_SUBTYPE_ENABLED = true; 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public static final int SUBTYPE_COMBINED = -1; 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) final int mType; 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) final int mSubType; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final String mSubscriberId; 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) final String mNetworkId; 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) final boolean mRoaming; 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public NetworkIdentity( 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, int subType, String subscriberId, String networkId, boolean roaming) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mType = type; 55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType; 56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mSubscriberId = subscriberId; 57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mNetworkId = networkId; 58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mRoaming = roaming; 59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch @Override 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public int hashCode() { 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming); 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) @Override 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public boolean equals(Object obj) { 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (obj instanceof NetworkIdentity) { 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) final NetworkIdentity ident = (NetworkIdentity) obj; 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) && Objects.equals(mSubscriberId, ident.mSubscriberId) 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) && Objects.equals(mNetworkId, ident.mNetworkId); 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @Override 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public String toString() { 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) final StringBuilder builder = new StringBuilder("{"); 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) builder.append("type=").append(getNetworkTypeName(mType)); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) builder.append(", subType="); 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (COMBINE_SUBTYPE_ENABLED) { 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) builder.append("COMBINED"); 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (ConnectivityManager.isNetworkTypeMobile(mType)) { 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) builder.append(TelephonyManager.getNetworkTypeName(mSubType)); 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch builder.append(mSubType); 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (mSubscriberId != null) { 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) builder.append(", subscriberId=").append(scrubSubscriberId(mSubscriberId)); 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (mNetworkId != null) { 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) builder.append(", networkId=").append(mNetworkId); 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (mRoaming) { 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) builder.append(", ROAMING"); 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return builder.append("}").toString(); 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public int getType() { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return mType; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public int getSubType() { 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return mSubType; 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public String getSubscriberId() { 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return mSubscriberId; 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public String getNetworkId() { 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return mNetworkId; 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public boolean getRoaming() { 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return mRoaming; 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Scrub given IMSI on production builds. 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public static String scrubSubscriberId(String subscriberId) { 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if ("eng".equals(Build.TYPE)) { 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return subscriberId; 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (subscriberId != null) { 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO: parse this as MCC+MNC instead of hard-coding 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return subscriberId.substring(0, Math.min(6, subscriberId.length())) + "..."; 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return "null"; 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch /** 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Build a {@link NetworkIdentity} from the given {@link NetworkState}, 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * assuming that any mobile networks are using the current IMSI. 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state) { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int type = state.networkInfo.getType(); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) final int subType = state.networkInfo.getSubtype(); 1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO: consider moving subscriberId over to LinkCapabilities, so it 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // comes from an authoritative source. 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) String subscriberId = null; 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) String networkId = null; 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) boolean roaming = false; 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (isNetworkTypeMobile(type)) { 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) final TelephonyManager telephony = (TelephonyManager) context.getSystemService( 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Context.TELEPHONY_SERVICE); 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) roaming = telephony.isNetworkRoaming(); 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (state.subscriberId != null) { 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) subscriberId = state.subscriberId; 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) subscriberId = telephony.getSubscriberId(); 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (type == TYPE_WIFI) { 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (state.networkId != null) { 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) networkId = state.networkId; 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) final WifiManager wifi = (WifiManager) context.getSystemService( 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Context.WIFI_SERVICE); 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) final WifiInfo info = wifi.getConnectionInfo(); 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) networkId = info != null ? info.getSSID() : null; 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return new NetworkIdentity(type, subType, subscriberId, networkId, roaming); 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @Override 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public int compareTo(NetworkIdentity another) { 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int res = Integer.compare(mType, another.mType); 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (res == 0) { 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) res = Integer.compare(mSubType, another.mSubType); 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (res == 0 && mSubscriberId != null && another.mSubscriberId != null) { 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) res = mSubscriberId.compareTo(another.mSubscriberId); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 183 if (res == 0 && mNetworkId != null && another.mNetworkId != null) { 184 res = mNetworkId.compareTo(another.mNetworkId); 185 } 186 if (res == 0) { 187 res = Boolean.compare(mRoaming, another.mRoaming); 188 } 189 return res; 190 } 191} 192