NetworkTemplate.java revision 7f8d650ed75ce6f3934c62f971683fa806201e51
11b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey/*
21b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Copyright (C) 2011 The Android Open Source Project
31b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey *
41b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
51b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * you may not use this file except in compliance with the License.
61b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * You may obtain a copy of the License at
71b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey *
81b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
91b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey *
101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
121b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * See the License for the specific language governing permissions and
141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * limitations under the License.
151b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */
161b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
171b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeypackage android.net;
181b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_BLUETOOTH;
2002e21d6a5b5117d494777a36783909854854f751Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_ETHERNET;
217f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavatiimport static android.net.ConnectivityManager.TYPE_PROXY;
221b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI;
233ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI_P2P;
241b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIMAX;
25d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkeyimport static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED;
262e4dce0dd24aa89ca6adf6559f13d3e342ff8558Jeff Sharkeyimport static android.net.wifi.WifiInfo.removeDoubleQuotes;
271b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_2_G;
281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_3_G;
291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_4_G;
301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN;
311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.getNetworkClass;
32adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
33630a1712168f402653039e368259cb9480454fa8Jeff Sharkeyimport static com.android.internal.util.ArrayUtils.contains;
341b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
35630a1712168f402653039e368259cb9480454fa8Jeff Sharkeyimport android.content.res.Resources;
361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.os.Parcel;
371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.os.Parcelable;
38adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport android.util.BackupUtils;
391b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
408b2c3a14603d163d7564e6f60286995079687690Jeff Sharkeyimport com.android.internal.annotations.VisibleForTesting;
413256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkeyimport com.android.internal.util.ArrayUtils;
421b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
43adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.ByteArrayOutputStream;
44adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.DataInputStream;
45adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.DataOutputStream;
46adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.IOException;
473256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkeyimport java.util.Arrays;
4855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkeyimport java.util.Objects;
4955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey/**
511b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Template definition used to generically match {@link NetworkIdentity},
521b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * usually when collecting statistics.
531b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey *
541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * @hide
551b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */
561b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeypublic class NetworkTemplate implements Parcelable {
57adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    /**
58adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy     * Current Version of the Backup Serializer.
59adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy     */
60adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    private static final int BACKUP_VERSION = 1;
611b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
624e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_MOBILE_ALL = 1;
636973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
644e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_MOBILE_3G_LOWER = 2;
656973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
664e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_MOBILE_4G = 3;
674e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_WIFI = 4;
684e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_ETHERNET = 5;
69234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static final int MATCH_MOBILE_WILDCARD = 6;
70234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static final int MATCH_WIFI_WILDCARD = 7;
7155a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    public static final int MATCH_BLUETOOTH = 8;
727f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    public static final int MATCH_PROXY = 9;
734e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
741b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
75630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Set of {@link NetworkInfo#getType()} that reflect data usage.
76630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     */
77630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    private static final int[] DATA_USAGE_NETWORK_TYPES;
78630a1712168f402653039e368259cb9480454fa8Jeff Sharkey
79630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    static {
80630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        DATA_USAGE_NETWORK_TYPES = Resources.getSystem().getIntArray(
81630a1712168f402653039e368259cb9480454fa8Jeff Sharkey                com.android.internal.R.array.config_data_usage_network_types);
82630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    }
83630a1712168f402653039e368259cb9480454fa8Jeff Sharkey
8470c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    private static boolean sForceAllNetworkTypes = false;
8570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
868b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey    @VisibleForTesting
8770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    public static void forceAllNetworkTypes() {
8870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        sForceAllNetworkTypes = true;
8970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    }
9070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
91630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    /**
928fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
938fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * the given IMSI.
941b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
954e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
968fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId, null);
974e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
991b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
1008fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
1018fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * the given IMSI that roughly meet a "3G" definition, or lower.
1021b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1038fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1044e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
1058fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId, null);
1064e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1081b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
1098fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
1108fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * the given IMSI that roughly meet a "4G" definition.
1111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1128fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1134e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
1148fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId, null);
1154e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1161b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1171b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
118234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks,
119234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     * regardless of IMSI.
120234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     */
121234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static NetworkTemplate buildTemplateMobileWildcard() {
122234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null);
123234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
124234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
125234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    /**
1268fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks,
1278fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * regardless of SSID.
1281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1298fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public static NetworkTemplate buildTemplateWifiWildcard() {
130234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return new NetworkTemplate(MATCH_WIFI_WILDCARD, null, null);
1318fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
1328fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
1338fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1344e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateWifi() {
1358fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return buildTemplateWifiWildcard();
1368fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
1378fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
1388fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    /**
1398fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
1408fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * given SSID.
1418fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     */
1428fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public static NetworkTemplate buildTemplateWifi(String networkId) {
1438fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_WIFI, null, networkId);
1444e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1464e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    /**
1474e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
1484e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * networks together.
1494e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     */
1504e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateEthernet() {
1518fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_ETHERNET, null, null);
1524e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1534e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
15455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    /**
15555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * Template to combine all {@link ConnectivityManager#TYPE_BLUETOOTH} style
15655a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * networks together.
15755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     */
15855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    public static NetworkTemplate buildTemplateBluetooth() {
15955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        return new NetworkTemplate(MATCH_BLUETOOTH, null, null);
16055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    }
16155a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
1627f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    /**
1637f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     * Template to combine all {@link ConnectivityManager#TYPE_PROXY} style
1647f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     * networks together.
1657f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     */
1667f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    public static NetworkTemplate buildTemplateProxy() {
1677f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati        return new NetworkTemplate(MATCH_PROXY, null, null);
1687f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    }
1697f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati
1704e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private final int mMatchRule;
1714e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private final String mSubscriberId;
1723256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1733256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    /**
1743256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Ugh, templates are designed to target a single subscriber, but we might
1753256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * need to match several "merged" subscribers. These are the subscribers
1763256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * that should be considered to match this template.
1773256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * <p>
1783256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Since the merge set is dynamic, it should <em>not</em> be persisted or
1793256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * used for determining equality.
1803256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     */
1813256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    private final String[] mMatchSubscriberIds;
1823256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1838fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    private final String mNetworkId;
1841b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1858fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
1863256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        this(matchRule, subscriberId, new String[] { subscriberId }, networkId);
1873256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
1883256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1893256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
1903256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            String networkId) {
1918fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mMatchRule = matchRule;
1928fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mSubscriberId = subscriberId;
1933256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        mMatchSubscriberIds = matchSubscriberIds;
1948fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mNetworkId = networkId;
1951b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
1961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1974e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private NetworkTemplate(Parcel in) {
1981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mMatchRule = in.readInt();
1991b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mSubscriberId = in.readString();
2003256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        mMatchSubscriberIds = in.createStringArray();
2018fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mNetworkId = in.readString();
2021b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2048fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Override
2051b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public void writeToParcel(Parcel dest, int flags) {
2061b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        dest.writeInt(mMatchRule);
2071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        dest.writeString(mSubscriberId);
2083256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        dest.writeStringArray(mMatchSubscriberIds);
2098fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        dest.writeString(mNetworkId);
2101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2128fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Override
2131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int describeContents() {
2141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return 0;
2151b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2161b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2171b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2181b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public String toString() {
2198fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        final StringBuilder builder = new StringBuilder("NetworkTemplate: ");
2208fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        builder.append("matchRule=").append(getMatchRuleName(mMatchRule));
2218fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        if (mSubscriberId != null) {
2223256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            builder.append(", subscriberId=").append(
2233256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    NetworkIdentity.scrubSubscriberId(mSubscriberId));
2243256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
2253256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        if (mMatchSubscriberIds != null) {
2263256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            builder.append(", matchSubscriberIds=").append(
2273256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    Arrays.toString(NetworkIdentity.scrubSubscriberId(mMatchSubscriberIds)));
2288fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        }
2298fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        if (mNetworkId != null) {
2308fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey            builder.append(", networkId=").append(mNetworkId);
2318fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        }
2328fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return builder.toString();
2331b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2341b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int hashCode() {
237e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root        return Objects.hash(mMatchRule, mSubscriberId, mNetworkId);
2381b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2391b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2401b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2411b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public boolean equals(Object obj) {
2421b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        if (obj instanceof NetworkTemplate) {
2431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            final NetworkTemplate other = (NetworkTemplate) obj;
2441b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return mMatchRule == other.mMatchRule
245e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                    && Objects.equals(mSubscriberId, other.mSubscriberId)
246e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                    && Objects.equals(mNetworkId, other.mNetworkId);
2471b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
2481b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
2491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2513256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public boolean isMatchRuleMobile() {
2523256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        switch (mMatchRule) {
2533256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_3G_LOWER:
2543256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_4G:
2553256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_ALL:
2563256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_WILDCARD:
2573256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                return true;
2583256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            default:
2593256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                return false;
2603256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
2613256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
2623256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
2637474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey    public boolean isPersistable() {
2647474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey        switch (mMatchRule) {
2657474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
2667474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            case MATCH_WIFI_WILDCARD:
2677474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey                return false;
2687474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            default:
2697474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey                return true;
2707474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey        }
2717474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey    }
2727474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey
2731b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int getMatchRule() {
2741b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return mMatchRule;
2751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2761b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2771b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public String getSubscriberId() {
2781b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return mSubscriberId;
2791b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2801b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2818fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public String getNetworkId() {
2828fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return mNetworkId;
2838fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
2848fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
2851b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
286630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Test if given {@link NetworkIdentity} matches this template.
2871b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
2881b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public boolean matches(NetworkIdentity ident) {
2891b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        switch (mMatchRule) {
2901b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_ALL:
2911b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile(ident);
2921b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_3G_LOWER:
2931b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile3gLower(ident);
2941b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_4G:
2951b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile4g(ident);
2961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_WIFI:
2971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesWifi(ident);
2984e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            case MATCH_ETHERNET:
2994e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey                return matchesEthernet(ident);
300234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
301234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return matchesMobileWildcard(ident);
302234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_WIFI_WILDCARD:
303234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return matchesWifiWildcard(ident);
30455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            case MATCH_BLUETOOTH:
30555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey                return matchesBluetooth(ident);
3067f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati            case MATCH_PROXY:
3077f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati                return matchesProxy(ident);
3081b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            default:
3091b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                throw new IllegalArgumentException("unknown network template");
3101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3121b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
314630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Check if mobile network with matching IMSI.
3151b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3161b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile(NetworkIdentity ident) {
317630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
318630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            // TODO: consider matching against WiMAX subscriber identity
3191b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return true;
320630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else {
3213256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            final boolean matchesType = (sForceAllNetworkTypes
3223256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    || contains(DATA_USAGE_NETWORK_TYPES, ident.mType));
32356859f323c1e7da9d537478e080d73614b207376Jeff Sharkey            return matchesType && !ArrayUtils.isEmpty(mMatchSubscriberIds)
32456859f323c1e7da9d537478e080d73614b207376Jeff Sharkey                    && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
3251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3271b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
32902e21d6a5b5117d494777a36783909854854f751Jeff Sharkey     * Check if mobile network classified 3G or lower with matching IMSI.
3301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3316973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
3321b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile3gLower(NetworkIdentity ident) {
333d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        ensureSubtypeAvailable();
334630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
335630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            return false;
336630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else if (matchesMobile(ident)) {
3371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            switch (getNetworkClass(ident.mSubType)) {
3381b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_UNKNOWN:
3391b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_2_G:
3401b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_3_G:
3411b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    return true;
3421b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            }
3431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3441b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
3451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3461b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3471b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
348630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Check if mobile network classified 4G with matching IMSI.
3491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3506973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
3511b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile4g(NetworkIdentity ident) {
352d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        ensureSubtypeAvailable();
353630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
354630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            // TODO: consider matching against WiMAX subscriber identity
355630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            return true;
356630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else if (matchesMobile(ident)) {
3571b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            switch (getNetworkClass(ident.mSubType)) {
3581b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_4_G:
3591b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    return true;
3601b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            }
3611b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
3631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3651b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
3661b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     * Check if matches Wi-Fi network template.
3671b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3681b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesWifi(NetworkIdentity ident) {
3693ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey        switch (ident.mType) {
3703ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey            case TYPE_WIFI:
371e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                return Objects.equals(
3722e4dce0dd24aa89ca6adf6559f13d3e342ff8558Jeff Sharkey                        removeDoubleQuotes(mNetworkId), removeDoubleQuotes(ident.mNetworkId));
3733ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey            default:
3743ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey                return false;
3751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3761b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3771b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3784e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    /**
3794e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * Check if matches Ethernet network template.
3804e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     */
3814e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private boolean matchesEthernet(NetworkIdentity ident) {
3824e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        if (ident.mType == TYPE_ETHERNET) {
3834e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            return true;
3844e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        }
3854e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        return false;
3864e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
3874e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
388234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private boolean matchesMobileWildcard(NetworkIdentity ident) {
389234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
390234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            return true;
391234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        } else {
39270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey            return sForceAllNetworkTypes || contains(DATA_USAGE_NETWORK_TYPES, ident.mType);
393234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        }
394234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
395234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
396234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private boolean matchesWifiWildcard(NetworkIdentity ident) {
397234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        switch (ident.mType) {
398234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case TYPE_WIFI:
399234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case TYPE_WIFI_P2P:
400234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return true;
401234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            default:
402234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return false;
403234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        }
404234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
405234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
40655a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    /**
40755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * Check if matches Bluetooth network template.
40855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     */
40955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    private boolean matchesBluetooth(NetworkIdentity ident) {
41055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        if (ident.mType == TYPE_BLUETOOTH) {
41155a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            return true;
41255a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        }
41355a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        return false;
41455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    }
41555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
4167f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    /**
4177f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     * Check if matches Proxy network template.
4187f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     */
4197f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    private boolean matchesProxy(NetworkIdentity ident) {
4207f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati        return ident.mType == TYPE_PROXY;
4217f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    }
4227f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati
4234e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private static String getMatchRuleName(int matchRule) {
4241b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        switch (matchRule) {
4251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_3G_LOWER:
4261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "MOBILE_3G_LOWER";
4271b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_4G:
4281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "MOBILE_4G";
4291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_ALL:
4301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "MOBILE_ALL";
4311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_WIFI:
4321b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "WIFI";
4334e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            case MATCH_ETHERNET:
4344e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey                return "ETHERNET";
435234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
436234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return "MOBILE_WILDCARD";
437234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_WIFI_WILDCARD:
438234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return "WIFI_WILDCARD";
43955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            case MATCH_BLUETOOTH:
44055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey                return "BLUETOOTH";
4417f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati            case MATCH_PROXY:
4427f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati                return "PROXY";
4431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            default:
4441b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "UNKNOWN";
4451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4461b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
4471b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
448d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey    private static void ensureSubtypeAvailable() {
449d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        if (COMBINE_SUBTYPE_ENABLED) {
450d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey            throw new IllegalArgumentException(
451d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey                    "Unable to enforce 3G_LOWER template on combined data.");
452d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        }
453d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey    }
454d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey
4553256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    /**
4563256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Examine the given template and normalize if it refers to a "merged"
4573256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * mobile subscriber. We pick the "lowest" merged subscriber as the primary
4583256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * for key purposes, and expand the template to match all other merged
4593256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * subscribers.
4603256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * <p>
4613256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * For example, given an incoming template matching B, and the currently
4623256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * active merge set [A,B], we'd return a new template that primarily matches
4633256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * A, but also matches B.
4643256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     */
4653256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public static NetworkTemplate normalize(NetworkTemplate template, String[] merged) {
4663256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        if (template.isMatchRuleMobile() && ArrayUtils.contains(merged, template.mSubscriberId)) {
4673256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            // Requested template subscriber is part of the merge group; return
4683256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            // a template that matches all merged subscribers.
4693256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            return new NetworkTemplate(template.mMatchRule, merged[0], merged,
4703256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    template.mNetworkId);
4713256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        } else {
4723256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            return template;
4733256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
4743256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
4753256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
4761b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public static final Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
4778fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        @Override
4781b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        public NetworkTemplate createFromParcel(Parcel in) {
4791b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return new NetworkTemplate(in);
4801b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4811b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
4828fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        @Override
4831b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        public NetworkTemplate[] newArray(int size) {
4841b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return new NetworkTemplate[size];
4851b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4861b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    };
487adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
488adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    public byte[] getBytesForBackup() throws IOException {
489adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        ByteArrayOutputStream baos = new ByteArrayOutputStream();
490adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        DataOutputStream out = new DataOutputStream(baos);
491adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
492adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        out.writeInt(BACKUP_VERSION);
493adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
494adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        out.writeInt(mMatchRule);
495adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        BackupUtils.writeString(out, mSubscriberId);
496adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        BackupUtils.writeString(out, mNetworkId);
497adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
498adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        return baos.toByteArray();
499adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    }
500adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
501adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    public static NetworkTemplate getNetworkTemplateFromBackup(DataInputStream in)
502adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy            throws IOException, BackupUtils.BadVersionException {
503adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        int version = in.readInt();
504adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        if (version < 1 || version > BACKUP_VERSION) {
505adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
506adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        }
507adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
508adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        int matchRule = in.readInt();
509adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        String subscriberId = BackupUtils.readString(in);
510adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        String networkId = BackupUtils.readString(in);
511adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
512adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        return new NetworkTemplate(matchRule, subscriberId, networkId);
513adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    }
5141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey}
515