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