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;
2166a6be3a4c955e52ea61e0d35f338983f632abf8Jack Yuimport static android.net.ConnectivityManager.TYPE_MOBILE;
223bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tateimport static android.net.ConnectivityManager.TYPE_PROXY;
231b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI;
243ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI_P2P;
251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIMAX;
26d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkeyimport static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED;
272e4dce0dd24aa89ca6adf6559f13d3e342ff8558Jeff Sharkeyimport static android.net.wifi.WifiInfo.removeDoubleQuotes;
281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_2_G;
291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_3_G;
301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_4_G;
311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN;
321b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.getNetworkClass;
33adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
341b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.os.Parcel;
351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.os.Parcelable;
36adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport android.util.BackupUtils;
373bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tateimport android.util.Log;
381b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
393256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkeyimport com.android.internal.util.ArrayUtils;
401b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
41adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.ByteArrayOutputStream;
42adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.DataInputStream;
43adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.DataOutputStream;
44adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.IOException;
453256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkeyimport java.util.Arrays;
4655a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkeyimport java.util.Objects;
4755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
481b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey/**
491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Template definition used to generically match {@link NetworkIdentity},
501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * usually when collecting statistics.
511b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey *
521b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * @hide
531b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */
541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeypublic class NetworkTemplate implements Parcelable {
553bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate    private static final String TAG = "NetworkTemplate";
563bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
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;
633bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate    /** @deprecated don't use this any more */
646973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
654e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_MOBILE_3G_LOWER = 2;
663bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate    /** @deprecated don't use this any more */
676973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
684e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_MOBILE_4G = 3;
694e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_WIFI = 4;
704e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_ETHERNET = 5;
71234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static final int MATCH_MOBILE_WILDCARD = 6;
72234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static final int MATCH_WIFI_WILDCARD = 7;
7355a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    public static final int MATCH_BLUETOOTH = 8;
747f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    public static final int MATCH_PROXY = 9;
754e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
763bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate    private static boolean isKnownMatchRule(final int rule) {
773bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        switch (rule) {
783bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_MOBILE_ALL:
793bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_MOBILE_3G_LOWER:
803bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_MOBILE_4G:
813bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_WIFI:
823bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_ETHERNET:
833bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_MOBILE_WILDCARD:
843bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_WIFI_WILDCARD:
853bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_BLUETOOTH:
863bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_PROXY:
873bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                return true;
883bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
893bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            default:
903bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                return false;
913bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        }
923bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate    }
933bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
9470c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    private static boolean sForceAllNetworkTypes = false;
9570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
9670c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    public static void forceAllNetworkTypes() {
9770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        sForceAllNetworkTypes = true;
9870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    }
9970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
100630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    /**
1018fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
1028fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * the given IMSI.
1031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1044e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
1058fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_ALL, 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 "3G" definition, or lower.
1111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1128fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1134e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
1148fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId, null);
1154e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1161b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1171b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
1188fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
1198fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * the given IMSI that roughly meet a "4G" definition.
1201b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1218fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1224e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
1238fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId, null);
1244e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
127234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks,
128234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     * regardless of IMSI.
129234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     */
130234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static NetworkTemplate buildTemplateMobileWildcard() {
131234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null);
132234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
133234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
134234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    /**
1358fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks,
1368fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * regardless of SSID.
1371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1388fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public static NetworkTemplate buildTemplateWifiWildcard() {
139234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return new NetworkTemplate(MATCH_WIFI_WILDCARD, null, null);
1408fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
1418fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
1428fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1434e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateWifi() {
1448fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return buildTemplateWifiWildcard();
1458fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
1468fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
1478fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    /**
1488fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
1498fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * given SSID.
1508fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     */
1518fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public static NetworkTemplate buildTemplateWifi(String networkId) {
1528fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_WIFI, null, networkId);
1534e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1554e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    /**
1564e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
1574e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * networks together.
1584e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     */
1594e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateEthernet() {
1608fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_ETHERNET, null, null);
1614e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1624e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
16355a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    /**
16455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * Template to combine all {@link ConnectivityManager#TYPE_BLUETOOTH} style
16555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * networks together.
16655a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     */
16755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    public static NetworkTemplate buildTemplateBluetooth() {
16855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        return new NetworkTemplate(MATCH_BLUETOOTH, null, null);
16955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    }
17055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
1717f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    /**
1727f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     * Template to combine all {@link ConnectivityManager#TYPE_PROXY} style
1737f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     * networks together.
1747f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     */
1757f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    public static NetworkTemplate buildTemplateProxy() {
1767f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati        return new NetworkTemplate(MATCH_PROXY, null, null);
1777f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    }
1787f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati
1794e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private final int mMatchRule;
1804e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private final String mSubscriberId;
1813256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1823256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    /**
1833256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Ugh, templates are designed to target a single subscriber, but we might
1843256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * need to match several "merged" subscribers. These are the subscribers
1853256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * that should be considered to match this template.
1863256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * <p>
1873256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Since the merge set is dynamic, it should <em>not</em> be persisted or
1883256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * used for determining equality.
1893256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     */
1903256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    private final String[] mMatchSubscriberIds;
1913256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1928fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    private final String mNetworkId;
1931b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1948fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
1953256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        this(matchRule, subscriberId, new String[] { subscriberId }, networkId);
1963256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
1973256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1983256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
1993256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            String networkId) {
2008fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mMatchRule = matchRule;
2018fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mSubscriberId = subscriberId;
2023256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        mMatchSubscriberIds = matchSubscriberIds;
2038fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mNetworkId = networkId;
2043bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
2053bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        if (!isKnownMatchRule(matchRule)) {
2063bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            Log.e(TAG, "Unknown network template rule " + matchRule
2073bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                    + " will not match any identity.");
2083bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        }
2091b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2114e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private NetworkTemplate(Parcel in) {
2121b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mMatchRule = in.readInt();
2131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mSubscriberId = in.readString();
2143256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        mMatchSubscriberIds = in.createStringArray();
2158fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mNetworkId = in.readString();
2161b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2171b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2188fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Override
2191b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public void writeToParcel(Parcel dest, int flags) {
2201b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        dest.writeInt(mMatchRule);
2211b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        dest.writeString(mSubscriberId);
2223256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        dest.writeStringArray(mMatchSubscriberIds);
2238fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        dest.writeString(mNetworkId);
2241b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2268fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Override
2271b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int describeContents() {
2281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return 0;
2291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2321b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public String toString() {
2338fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        final StringBuilder builder = new StringBuilder("NetworkTemplate: ");
2348fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        builder.append("matchRule=").append(getMatchRuleName(mMatchRule));
2358fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        if (mSubscriberId != null) {
2363256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            builder.append(", subscriberId=").append(
2373256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    NetworkIdentity.scrubSubscriberId(mSubscriberId));
2383256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
2393256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        if (mMatchSubscriberIds != null) {
2403256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            builder.append(", matchSubscriberIds=").append(
2413256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    Arrays.toString(NetworkIdentity.scrubSubscriberId(mMatchSubscriberIds)));
2428fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        }
2438fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        if (mNetworkId != null) {
2448fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey            builder.append(", networkId=").append(mNetworkId);
2458fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        }
2468fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return builder.toString();
2471b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2481b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int hashCode() {
251e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root        return Objects.hash(mMatchRule, mSubscriberId, mNetworkId);
2521b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2531b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2551b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public boolean equals(Object obj) {
2561b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        if (obj instanceof NetworkTemplate) {
2571b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            final NetworkTemplate other = (NetworkTemplate) obj;
2581b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return mMatchRule == other.mMatchRule
259e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                    && Objects.equals(mSubscriberId, other.mSubscriberId)
260e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                    && Objects.equals(mNetworkId, other.mNetworkId);
2611b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
2621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
2631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2653256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public boolean isMatchRuleMobile() {
2663256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        switch (mMatchRule) {
2673256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_3G_LOWER:
2683256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_4G:
2693256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_ALL:
2703256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_WILDCARD:
2713256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                return true;
2723256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            default:
2733256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                return false;
2743256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
2753256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
2763256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
2777474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey    public boolean isPersistable() {
2787474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey        switch (mMatchRule) {
2797474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
2807474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            case MATCH_WIFI_WILDCARD:
2817474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey                return false;
2827474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            default:
2837474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey                return true;
2847474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey        }
2857474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey    }
2867474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey
2871b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int getMatchRule() {
2881b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return mMatchRule;
2891b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2901b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2911b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public String getSubscriberId() {
2921b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return mSubscriberId;
2931b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2941b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2958fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public String getNetworkId() {
2968fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return mNetworkId;
2978fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
2988fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
2991b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
300630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Test if given {@link NetworkIdentity} matches this template.
3011b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3021b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public boolean matches(NetworkIdentity ident) {
3031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        switch (mMatchRule) {
3041b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_ALL:
3051b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile(ident);
3061b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_3G_LOWER:
3071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile3gLower(ident);
3081b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_4G:
3091b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile4g(ident);
3101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_WIFI:
3111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesWifi(ident);
3124e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            case MATCH_ETHERNET:
3134e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey                return matchesEthernet(ident);
314234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
315234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return matchesMobileWildcard(ident);
316234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_WIFI_WILDCARD:
317234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return matchesWifiWildcard(ident);
31855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            case MATCH_BLUETOOTH:
31955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey                return matchesBluetooth(ident);
3207f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati            case MATCH_PROXY:
3217f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati                return matchesProxy(ident);
3221b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            default:
3233bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                // We have no idea what kind of network template we are, so we
3243bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                // just claim not to match anything.
3253bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                return false;
3261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3271b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
329f4de294297de47d8c594956b2d8607e314e71836Jeff Sharkey    public boolean matchesSubscriberId(String subscriberId) {
330f4de294297de47d8c594956b2d8607e314e71836Jeff Sharkey        return ArrayUtils.contains(mMatchSubscriberIds, subscriberId);
331f4de294297de47d8c594956b2d8607e314e71836Jeff Sharkey    }
332f4de294297de47d8c594956b2d8607e314e71836Jeff Sharkey
3331b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
334630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Check if mobile network with matching IMSI.
3351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile(NetworkIdentity ident) {
337630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
338630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            // TODO: consider matching against WiMAX subscriber identity
3391b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return true;
340630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else {
34166a6be3a4c955e52ea61e0d35f338983f632abf8Jack Yu            return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered))
34266a6be3a4c955e52ea61e0d35f338983f632abf8Jack Yu                    && !ArrayUtils.isEmpty(mMatchSubscriberIds)
34356859f323c1e7da9d537478e080d73614b207376Jeff Sharkey                    && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
3441b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3461b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3471b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
34802e21d6a5b5117d494777a36783909854854f751Jeff Sharkey     * Check if mobile network classified 3G or lower with matching IMSI.
3491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3506973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
3511b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile3gLower(NetworkIdentity ident) {
352d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        ensureSubtypeAvailable();
353630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
354630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            return false;
355630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else if (matchesMobile(ident)) {
3561b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            switch (getNetworkClass(ident.mSubType)) {
3571b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_UNKNOWN:
3581b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_2_G:
3591b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_3_G:
3601b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    return true;
3611b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            }
3621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
3641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3651b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3661b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
367630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Check if mobile network classified 4G with matching IMSI.
3681b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3696973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
3701b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile4g(NetworkIdentity ident) {
371d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        ensureSubtypeAvailable();
372630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
373630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            // TODO: consider matching against WiMAX subscriber identity
374630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            return true;
375630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else if (matchesMobile(ident)) {
3761b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            switch (getNetworkClass(ident.mSubType)) {
3771b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_4_G:
3781b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    return true;
3791b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            }
3801b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3811b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
3821b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3831b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3841b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
3851b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     * Check if matches Wi-Fi network template.
3861b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3871b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesWifi(NetworkIdentity ident) {
3883ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey        switch (ident.mType) {
3893ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey            case TYPE_WIFI:
390e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                return Objects.equals(
3912e4dce0dd24aa89ca6adf6559f13d3e342ff8558Jeff Sharkey                        removeDoubleQuotes(mNetworkId), removeDoubleQuotes(ident.mNetworkId));
3923ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey            default:
3933ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey                return false;
3941b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3951b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3974e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    /**
3984e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * Check if matches Ethernet network template.
3994e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     */
4004e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private boolean matchesEthernet(NetworkIdentity ident) {
4014e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        if (ident.mType == TYPE_ETHERNET) {
4024e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            return true;
4034e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        }
4044e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        return false;
4054e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
4064e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
407234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private boolean matchesMobileWildcard(NetworkIdentity ident) {
408234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
409234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            return true;
410234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        } else {
41166a6be3a4c955e52ea61e0d35f338983f632abf8Jack Yu            return sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered);
412234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        }
413234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
414234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
415234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private boolean matchesWifiWildcard(NetworkIdentity ident) {
416234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        switch (ident.mType) {
417234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case TYPE_WIFI:
418234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case TYPE_WIFI_P2P:
419234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return true;
420234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            default:
421234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return false;
422234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        }
423234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
424234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
42555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    /**
42655a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * Check if matches Bluetooth network template.
42755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     */
42855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    private boolean matchesBluetooth(NetworkIdentity ident) {
42955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        if (ident.mType == TYPE_BLUETOOTH) {
43055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            return true;
43155a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        }
43255a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        return false;
43355a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    }
43455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
4357f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    /**
4367f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     * Check if matches Proxy network template.
4377f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     */
4387f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    private boolean matchesProxy(NetworkIdentity ident) {
4397f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati        return ident.mType == TYPE_PROXY;
4407f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    }
4417f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati
4424e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private static String getMatchRuleName(int matchRule) {
4431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        switch (matchRule) {
4441b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_3G_LOWER:
4451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "MOBILE_3G_LOWER";
4461b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_4G:
4471b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "MOBILE_4G";
4481b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_ALL:
4491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "MOBILE_ALL";
4501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_WIFI:
4511b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "WIFI";
4524e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            case MATCH_ETHERNET:
4534e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey                return "ETHERNET";
454234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
455234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return "MOBILE_WILDCARD";
456234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_WIFI_WILDCARD:
457234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return "WIFI_WILDCARD";
45855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            case MATCH_BLUETOOTH:
45955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey                return "BLUETOOTH";
4607f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati            case MATCH_PROXY:
4617f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati                return "PROXY";
4621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            default:
4633bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                return "UNKNOWN(" + matchRule + ")";
4641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4651b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
4661b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
467d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey    private static void ensureSubtypeAvailable() {
468d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        if (COMBINE_SUBTYPE_ENABLED) {
469d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey            throw new IllegalArgumentException(
470d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey                    "Unable to enforce 3G_LOWER template on combined data.");
471d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        }
472d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey    }
473d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey
4743256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    /**
4753256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Examine the given template and normalize if it refers to a "merged"
4763256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * mobile subscriber. We pick the "lowest" merged subscriber as the primary
4773256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * for key purposes, and expand the template to match all other merged
4783256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * subscribers.
4793256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * <p>
4803256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * For example, given an incoming template matching B, and the currently
4813256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * active merge set [A,B], we'd return a new template that primarily matches
4823256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * A, but also matches B.
4833256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     */
4843256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public static NetworkTemplate normalize(NetworkTemplate template, String[] merged) {
4853256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        if (template.isMatchRuleMobile() && ArrayUtils.contains(merged, template.mSubscriberId)) {
4863256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            // Requested template subscriber is part of the merge group; return
4873256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            // a template that matches all merged subscribers.
4883256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            return new NetworkTemplate(template.mMatchRule, merged[0], merged,
4893256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    template.mNetworkId);
4903256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        } else {
4913256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            return template;
4923256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
4933256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
4943256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
4951b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public static final Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
4968fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        @Override
4971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        public NetworkTemplate createFromParcel(Parcel in) {
4981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return new NetworkTemplate(in);
4991b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
5001b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
5018fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        @Override
5021b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        public NetworkTemplate[] newArray(int size) {
5031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return new NetworkTemplate[size];
5041b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
5051b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    };
506adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
507adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    public byte[] getBytesForBackup() throws IOException {
508adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        ByteArrayOutputStream baos = new ByteArrayOutputStream();
509adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        DataOutputStream out = new DataOutputStream(baos);
510adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
511adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        out.writeInt(BACKUP_VERSION);
512adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
513adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        out.writeInt(mMatchRule);
514adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        BackupUtils.writeString(out, mSubscriberId);
515adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        BackupUtils.writeString(out, mNetworkId);
516adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
517adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        return baos.toByteArray();
518adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    }
519adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
520adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    public static NetworkTemplate getNetworkTemplateFromBackup(DataInputStream in)
521adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy            throws IOException, BackupUtils.BadVersionException {
522adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        int version = in.readInt();
523adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        if (version < 1 || version > BACKUP_VERSION) {
524adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
525adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        }
526adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
527adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        int matchRule = in.readInt();
528adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        String subscriberId = BackupUtils.readString(in);
529adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        String networkId = BackupUtils.readString(in);
530adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
5313bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        if (!isKnownMatchRule(matchRule)) {
5323bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            throw new BackupUtils.BadVersionException(
5333bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                    "Restored network template contains unknown match rule " + matchRule);
5343bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        }
5353bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
536adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        return new NetworkTemplate(matchRule, subscriberId, networkId);
537adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    }
5381b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey}
539