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
17package android.net;
18
19import static android.net.ConnectivityManager.isNetworkTypeMobile;
20
21import android.content.Context;
22import android.os.Build;
23import android.telephony.TelephonyManager;
24
25import com.android.internal.util.Objects;
26
27/**
28 * Network definition that includes strong identity. Analogous to combining
29 * {@link NetworkInfo} and an IMSI.
30 *
31 * @hide
32 */
33public class NetworkIdentity {
34    final int mType;
35    final int mSubType;
36    final String mSubscriberId;
37    final boolean mRoaming;
38
39    public NetworkIdentity(int type, int subType, String subscriberId, boolean roaming) {
40        this.mType = type;
41        this.mSubType = subType;
42        this.mSubscriberId = subscriberId;
43        this.mRoaming = roaming;
44    }
45
46    @Override
47    public int hashCode() {
48        return Objects.hashCode(mType, mSubType, mSubscriberId);
49    }
50
51    @Override
52    public boolean equals(Object obj) {
53        if (obj instanceof NetworkIdentity) {
54            final NetworkIdentity ident = (NetworkIdentity) obj;
55            return mType == ident.mType && mSubType == ident.mSubType
56                    && Objects.equal(mSubscriberId, ident.mSubscriberId)
57                    && mRoaming == ident.mRoaming;
58        }
59        return false;
60    }
61
62    @Override
63    public String toString() {
64        final String typeName = ConnectivityManager.getNetworkTypeName(mType);
65        final String subTypeName;
66        if (ConnectivityManager.isNetworkTypeMobile(mType)) {
67            subTypeName = TelephonyManager.getNetworkTypeName(mSubType);
68        } else {
69            subTypeName = Integer.toString(mSubType);
70        }
71
72        final String scrubSubscriberId = scrubSubscriberId(mSubscriberId);
73        final String roaming = mRoaming ? ", ROAMING" : "";
74        return "[type=" + typeName + ", subType=" + subTypeName + ", subscriberId="
75                + scrubSubscriberId + roaming + "]";
76    }
77
78    public int getType() {
79        return mType;
80    }
81
82    public int getSubType() {
83        return mSubType;
84    }
85
86    public String getSubscriberId() {
87        return mSubscriberId;
88    }
89
90    public boolean getRoaming() {
91        return mRoaming;
92    }
93
94    /**
95     * Scrub given IMSI on production builds.
96     */
97    public static String scrubSubscriberId(String subscriberId) {
98        if ("eng".equals(Build.TYPE)) {
99            return subscriberId;
100        } else {
101            return subscriberId != null ? "valid" : "null";
102        }
103    }
104
105    /**
106     * Build a {@link NetworkIdentity} from the given {@link NetworkState},
107     * assuming that any mobile networks are using the current IMSI.
108     */
109    public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state) {
110        final int type = state.networkInfo.getType();
111        final int subType = state.networkInfo.getSubtype();
112
113        // TODO: consider moving subscriberId over to LinkCapabilities, so it
114        // comes from an authoritative source.
115
116        final String subscriberId;
117        final boolean roaming;
118        if (isNetworkTypeMobile(type)) {
119            final TelephonyManager telephony = (TelephonyManager) context.getSystemService(
120                    Context.TELEPHONY_SERVICE);
121            roaming = telephony.isNetworkRoaming();
122            if (state.subscriberId != null) {
123                subscriberId = state.subscriberId;
124            } else {
125                subscriberId = telephony.getSubscriberId();
126            }
127        } else {
128            subscriberId = null;
129            roaming = false;
130        }
131        return new NetworkIdentity(type, subType, subscriberId, roaming);
132    }
133
134}
135