NetworkTemplate.java revision 3ca7481439c9b65a137d7705d0f4a16766529e75
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.TYPE_ETHERNET;
20import static android.net.ConnectivityManager.TYPE_WIFI;
21import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
22import static android.net.ConnectivityManager.TYPE_WIMAX;
23import static android.net.NetworkIdentity.scrubSubscriberId;
24import static android.telephony.TelephonyManager.NETWORK_CLASS_2_G;
25import static android.telephony.TelephonyManager.NETWORK_CLASS_3_G;
26import static android.telephony.TelephonyManager.NETWORK_CLASS_4_G;
27import static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN;
28import static android.telephony.TelephonyManager.getNetworkClass;
29import static com.android.internal.util.ArrayUtils.contains;
30
31import android.content.res.Resources;
32import android.os.Parcel;
33import android.os.Parcelable;
34
35import com.android.internal.util.Objects;
36
37/**
38 * Template definition used to generically match {@link NetworkIdentity},
39 * usually when collecting statistics.
40 *
41 * @hide
42 */
43public class NetworkTemplate implements Parcelable {
44
45    /** {@hide} */
46    public static final int MATCH_MOBILE_ALL = 1;
47    /** {@hide} */
48    public static final int MATCH_MOBILE_3G_LOWER = 2;
49    /** {@hide} */
50    public static final int MATCH_MOBILE_4G = 3;
51    /** {@hide} */
52    public static final int MATCH_WIFI = 4;
53    /** {@hide} */
54    public static final int MATCH_ETHERNET = 5;
55
56    /**
57     * Set of {@link NetworkInfo#getType()} that reflect data usage.
58     */
59    private static final int[] DATA_USAGE_NETWORK_TYPES;
60
61    static {
62        DATA_USAGE_NETWORK_TYPES = Resources.getSystem().getIntArray(
63                com.android.internal.R.array.config_data_usage_network_types);
64    }
65
66    /**
67     * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
68     * networks together. Only uses statistics for requested IMSI.
69     */
70    public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
71        return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId);
72    }
73
74    /**
75     * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
76     * networks together that roughly meet a "3G" definition, or lower. Only
77     * uses statistics for requested IMSI.
78     */
79    public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
80        return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId);
81    }
82
83    /**
84     * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
85     * networks together that meet a "4G" definition. Only uses statistics for
86     * requested IMSI.
87     */
88    public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
89        return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId);
90    }
91
92    /**
93     * Template to combine all {@link ConnectivityManager#TYPE_WIFI} style
94     * networks together.
95     */
96    public static NetworkTemplate buildTemplateWifi() {
97        return new NetworkTemplate(MATCH_WIFI, null);
98    }
99
100    /**
101     * Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
102     * networks together.
103     */
104    public static NetworkTemplate buildTemplateEthernet() {
105        return new NetworkTemplate(MATCH_ETHERNET, null);
106    }
107
108    private final int mMatchRule;
109    private final String mSubscriberId;
110
111    /** {@hide} */
112    public NetworkTemplate(int matchRule, String subscriberId) {
113        this.mMatchRule = matchRule;
114        this.mSubscriberId = subscriberId;
115    }
116
117    private NetworkTemplate(Parcel in) {
118        mMatchRule = in.readInt();
119        mSubscriberId = in.readString();
120    }
121
122    /** {@inheritDoc} */
123    public void writeToParcel(Parcel dest, int flags) {
124        dest.writeInt(mMatchRule);
125        dest.writeString(mSubscriberId);
126    }
127
128    /** {@inheritDoc} */
129    public int describeContents() {
130        return 0;
131    }
132
133    @Override
134    public String toString() {
135        final String scrubSubscriberId = scrubSubscriberId(mSubscriberId);
136        return "NetworkTemplate: matchRule=" + getMatchRuleName(mMatchRule) + ", subscriberId="
137                + scrubSubscriberId;
138    }
139
140    @Override
141    public int hashCode() {
142        return Objects.hashCode(mMatchRule, mSubscriberId);
143    }
144
145    @Override
146    public boolean equals(Object obj) {
147        if (obj instanceof NetworkTemplate) {
148            final NetworkTemplate other = (NetworkTemplate) obj;
149            return mMatchRule == other.mMatchRule
150                    && Objects.equal(mSubscriberId, other.mSubscriberId);
151        }
152        return false;
153    }
154
155    /** {@hide} */
156    public int getMatchRule() {
157        return mMatchRule;
158    }
159
160    /** {@hide} */
161    public String getSubscriberId() {
162        return mSubscriberId;
163    }
164
165    /**
166     * Test if given {@link NetworkIdentity} matches this template.
167     */
168    public boolean matches(NetworkIdentity ident) {
169        switch (mMatchRule) {
170            case MATCH_MOBILE_ALL:
171                return matchesMobile(ident);
172            case MATCH_MOBILE_3G_LOWER:
173                return matchesMobile3gLower(ident);
174            case MATCH_MOBILE_4G:
175                return matchesMobile4g(ident);
176            case MATCH_WIFI:
177                return matchesWifi(ident);
178            case MATCH_ETHERNET:
179                return matchesEthernet(ident);
180            default:
181                throw new IllegalArgumentException("unknown network template");
182        }
183    }
184
185    /**
186     * Check if mobile network with matching IMSI.
187     */
188    private boolean matchesMobile(NetworkIdentity ident) {
189        if (ident.mType == TYPE_WIMAX) {
190            // TODO: consider matching against WiMAX subscriber identity
191            return true;
192        } else {
193            return (contains(DATA_USAGE_NETWORK_TYPES, ident.mType)
194                    && Objects.equal(mSubscriberId, ident.mSubscriberId));
195        }
196    }
197
198    /**
199     * Check if mobile network classified 3G or lower with matching IMSI.
200     */
201    private boolean matchesMobile3gLower(NetworkIdentity ident) {
202        if (ident.mType == TYPE_WIMAX) {
203            return false;
204        } else if (matchesMobile(ident)) {
205            switch (getNetworkClass(ident.mSubType)) {
206                case NETWORK_CLASS_UNKNOWN:
207                case NETWORK_CLASS_2_G:
208                case NETWORK_CLASS_3_G:
209                    return true;
210            }
211        }
212        return false;
213    }
214
215    /**
216     * Check if mobile network classified 4G with matching IMSI.
217     */
218    private boolean matchesMobile4g(NetworkIdentity ident) {
219        if (ident.mType == TYPE_WIMAX) {
220            // TODO: consider matching against WiMAX subscriber identity
221            return true;
222        } else if (matchesMobile(ident)) {
223            switch (getNetworkClass(ident.mSubType)) {
224                case NETWORK_CLASS_4_G:
225                    return true;
226            }
227        }
228        return false;
229    }
230
231    /**
232     * Check if matches Wi-Fi network template.
233     */
234    private boolean matchesWifi(NetworkIdentity ident) {
235        switch (ident.mType) {
236            case TYPE_WIFI:
237            case TYPE_WIFI_P2P:
238                return true;
239            default:
240                return false;
241        }
242    }
243
244    /**
245     * Check if matches Ethernet network template.
246     */
247    private boolean matchesEthernet(NetworkIdentity ident) {
248        if (ident.mType == TYPE_ETHERNET) {
249            return true;
250        }
251        return false;
252    }
253
254    private static String getMatchRuleName(int matchRule) {
255        switch (matchRule) {
256            case MATCH_MOBILE_3G_LOWER:
257                return "MOBILE_3G_LOWER";
258            case MATCH_MOBILE_4G:
259                return "MOBILE_4G";
260            case MATCH_MOBILE_ALL:
261                return "MOBILE_ALL";
262            case MATCH_WIFI:
263                return "WIFI";
264            case MATCH_ETHERNET:
265                return "ETHERNET";
266            default:
267                return "UNKNOWN";
268        }
269    }
270
271    public static final Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
272        public NetworkTemplate createFromParcel(Parcel in) {
273            return new NetworkTemplate(in);
274        }
275
276        public NetworkTemplate[] newArray(int size) {
277            return new NetworkTemplate[size];
278        }
279    };
280}
281