NetworkTemplate.java revision 7474fe7b421dcc190c4602389ca0f9c910382260
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;
211b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI;
223ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI_P2P;
231b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIMAX;
24d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkeyimport static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED;
252e4dce0dd24aa89ca6adf6559f13d3e342ff8558Jeff Sharkeyimport static android.net.wifi.WifiInfo.removeDoubleQuotes;
261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_2_G;
271b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_3_G;
281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_4_G;
291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN;
301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.telephony.TelephonyManager.getNetworkClass;
31adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
32630a1712168f402653039e368259cb9480454fa8Jeff Sharkeyimport static com.android.internal.util.ArrayUtils.contains;
331b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
34630a1712168f402653039e368259cb9480454fa8Jeff Sharkeyimport android.content.res.Resources;
351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.os.Parcel;
361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.os.Parcelable;
37adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport android.util.BackupUtils;
381b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
398b2c3a14603d163d7564e6f60286995079687690Jeff Sharkeyimport com.android.internal.annotations.VisibleForTesting;
403256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkeyimport com.android.internal.util.ArrayUtils;
411b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
42adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.ByteArrayOutputStream;
43adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.DataInputStream;
44adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.DataOutputStream;
45adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.IOException;
463256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkeyimport java.util.Arrays;
4755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkeyimport java.util.Objects;
4855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey/**
501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Template definition used to generically match {@link NetworkIdentity},
511b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * usually when collecting statistics.
521b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey *
531b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * @hide
541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */
551b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeypublic class NetworkTemplate implements Parcelable {
56adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    /**
57adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy     * Current Version of the Backup Serializer.
58adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy     */
59adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    private static final int BACKUP_VERSION = 1;
601b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
614e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_MOBILE_ALL = 1;
626973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
634e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_MOBILE_3G_LOWER = 2;
646973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
654e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_MOBILE_4G = 3;
664e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_WIFI = 4;
674e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static final int MATCH_ETHERNET = 5;
68234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static final int MATCH_MOBILE_WILDCARD = 6;
69234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static final int MATCH_WIFI_WILDCARD = 7;
7055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    public static final int MATCH_BLUETOOTH = 8;
714e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
721b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
73630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Set of {@link NetworkInfo#getType()} that reflect data usage.
74630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     */
75630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    private static final int[] DATA_USAGE_NETWORK_TYPES;
76630a1712168f402653039e368259cb9480454fa8Jeff Sharkey
77630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    static {
78630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        DATA_USAGE_NETWORK_TYPES = Resources.getSystem().getIntArray(
79630a1712168f402653039e368259cb9480454fa8Jeff Sharkey                com.android.internal.R.array.config_data_usage_network_types);
80630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    }
81630a1712168f402653039e368259cb9480454fa8Jeff Sharkey
8270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    private static boolean sForceAllNetworkTypes = false;
8370c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
848b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey    @VisibleForTesting
8570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    public static void forceAllNetworkTypes() {
8670c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        sForceAllNetworkTypes = true;
8770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    }
8870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
89630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    /**
908fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
918fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * the given IMSI.
921b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
934e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
948fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId, null);
954e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
988fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
998fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * the given IMSI that roughly meet a "3G" definition, or lower.
1001b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1018fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1024e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
1038fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId, null);
1044e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1051b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1061b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
1078fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
1088fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * the given IMSI that roughly meet a "4G" definition.
1091b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1108fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1114e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
1128fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId, null);
1134e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1151b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
116234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks,
117234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     * regardless of IMSI.
118234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     */
119234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static NetworkTemplate buildTemplateMobileWildcard() {
120234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null);
121234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
122234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
123234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    /**
1248fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks,
1258fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * regardless of SSID.
1261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1278fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public static NetworkTemplate buildTemplateWifiWildcard() {
128234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return new NetworkTemplate(MATCH_WIFI_WILDCARD, null, null);
1298fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
1308fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
1318fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1324e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateWifi() {
1338fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return buildTemplateWifiWildcard();
1348fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
1358fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
1368fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    /**
1378fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
1388fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * given SSID.
1398fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     */
1408fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public static NetworkTemplate buildTemplateWifi(String networkId) {
1418fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_WIFI, null, networkId);
1424e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1444e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    /**
1454e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
1464e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * networks together.
1474e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     */
1484e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateEthernet() {
1498fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_ETHERNET, null, null);
1504e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1514e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
15255a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    /**
15355a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * Template to combine all {@link ConnectivityManager#TYPE_BLUETOOTH} style
15455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * networks together.
15555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     */
15655a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    public static NetworkTemplate buildTemplateBluetooth() {
15755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        return new NetworkTemplate(MATCH_BLUETOOTH, null, null);
15855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    }
15955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
1604e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private final int mMatchRule;
1614e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private final String mSubscriberId;
1623256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1633256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    /**
1643256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Ugh, templates are designed to target a single subscriber, but we might
1653256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * need to match several "merged" subscribers. These are the subscribers
1663256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * that should be considered to match this template.
1673256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * <p>
1683256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Since the merge set is dynamic, it should <em>not</em> be persisted or
1693256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * used for determining equality.
1703256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     */
1713256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    private final String[] mMatchSubscriberIds;
1723256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1738fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    private final String mNetworkId;
1741b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1758fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
1763256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        this(matchRule, subscriberId, new String[] { subscriberId }, networkId);
1773256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
1783256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1793256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
1803256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            String networkId) {
1818fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mMatchRule = matchRule;
1828fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mSubscriberId = subscriberId;
1833256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        mMatchSubscriberIds = matchSubscriberIds;
1848fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mNetworkId = networkId;
1851b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
1861b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1874e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private NetworkTemplate(Parcel in) {
1881b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mMatchRule = in.readInt();
1891b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mSubscriberId = in.readString();
1903256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        mMatchSubscriberIds = in.createStringArray();
1918fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mNetworkId = in.readString();
1921b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
1931b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1948fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Override
1951b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public void writeToParcel(Parcel dest, int flags) {
1961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        dest.writeInt(mMatchRule);
1971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        dest.writeString(mSubscriberId);
1983256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        dest.writeStringArray(mMatchSubscriberIds);
1998fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        dest.writeString(mNetworkId);
2001b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2011b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2028fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Override
2031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int describeContents() {
2041b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return 0;
2051b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2061b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2081b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public String toString() {
2098fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        final StringBuilder builder = new StringBuilder("NetworkTemplate: ");
2108fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        builder.append("matchRule=").append(getMatchRuleName(mMatchRule));
2118fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        if (mSubscriberId != null) {
2123256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            builder.append(", subscriberId=").append(
2133256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    NetworkIdentity.scrubSubscriberId(mSubscriberId));
2143256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
2153256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        if (mMatchSubscriberIds != null) {
2163256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            builder.append(", matchSubscriberIds=").append(
2173256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    Arrays.toString(NetworkIdentity.scrubSubscriberId(mMatchSubscriberIds)));
2188fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        }
2198fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        if (mNetworkId != null) {
2208fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey            builder.append(", networkId=").append(mNetworkId);
2218fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        }
2228fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return builder.toString();
2231b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2241b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int hashCode() {
227e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root        return Objects.hash(mMatchRule, mSubscriberId, mNetworkId);
2281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public boolean equals(Object obj) {
2321b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        if (obj instanceof NetworkTemplate) {
2331b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            final NetworkTemplate other = (NetworkTemplate) obj;
2341b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return mMatchRule == other.mMatchRule
235e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                    && Objects.equals(mSubscriberId, other.mSubscriberId)
236e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                    && Objects.equals(mNetworkId, other.mNetworkId);
2371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
2381b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
2391b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2401b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2413256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public boolean isMatchRuleMobile() {
2423256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        switch (mMatchRule) {
2433256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_3G_LOWER:
2443256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_4G:
2453256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_ALL:
2463256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_WILDCARD:
2473256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                return true;
2483256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            default:
2493256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                return false;
2503256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
2513256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
2523256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
2537474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey    public boolean isPersistable() {
2547474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey        switch (mMatchRule) {
2557474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
2567474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            case MATCH_WIFI_WILDCARD:
2577474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey                return false;
2587474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            default:
2597474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey                return true;
2607474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey        }
2617474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey    }
2627474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey
2631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int getMatchRule() {
2641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return mMatchRule;
2651b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2661b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2671b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public String getSubscriberId() {
2681b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return mSubscriberId;
2691b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2701b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2718fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public String getNetworkId() {
2728fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return mNetworkId;
2738fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
2748fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
2751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
276630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Test if given {@link NetworkIdentity} matches this template.
2771b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
2781b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public boolean matches(NetworkIdentity ident) {
2791b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        switch (mMatchRule) {
2801b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_ALL:
2811b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile(ident);
2821b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_3G_LOWER:
2831b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile3gLower(ident);
2841b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_4G:
2851b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile4g(ident);
2861b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_WIFI:
2871b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesWifi(ident);
2884e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            case MATCH_ETHERNET:
2894e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey                return matchesEthernet(ident);
290234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
291234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return matchesMobileWildcard(ident);
292234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_WIFI_WILDCARD:
293234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return matchesWifiWildcard(ident);
29455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            case MATCH_BLUETOOTH:
29555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey                return matchesBluetooth(ident);
2961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            default:
2971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                throw new IllegalArgumentException("unknown network template");
2981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
2991b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3001b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3011b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
302630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Check if mobile network with matching IMSI.
3031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3041b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile(NetworkIdentity ident) {
305630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
306630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            // TODO: consider matching against WiMAX subscriber identity
3071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return true;
308630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else {
3093256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            final boolean matchesType = (sForceAllNetworkTypes
3103256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    || contains(DATA_USAGE_NETWORK_TYPES, ident.mType));
31156859f323c1e7da9d537478e080d73614b207376Jeff Sharkey            return matchesType && !ArrayUtils.isEmpty(mMatchSubscriberIds)
31256859f323c1e7da9d537478e080d73614b207376Jeff Sharkey                    && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
3131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3151b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3161b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
31702e21d6a5b5117d494777a36783909854854f751Jeff Sharkey     * Check if mobile network classified 3G or lower with matching IMSI.
3181b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3196973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
3201b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile3gLower(NetworkIdentity ident) {
321d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        ensureSubtypeAvailable();
322630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
323630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            return false;
324630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else if (matchesMobile(ident)) {
3251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            switch (getNetworkClass(ident.mSubType)) {
3261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_UNKNOWN:
3271b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_2_G:
3281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_3_G:
3291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    return true;
3301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            }
3311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3321b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
3331b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3341b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
336630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Check if mobile network classified 4G with matching IMSI.
3371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3386973634ce61ab7d4c1d51c70be6d51725b89e7b9Jeff Sharkey    @Deprecated
3391b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile4g(NetworkIdentity ident) {
340d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        ensureSubtypeAvailable();
341630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
342630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            // TODO: consider matching against WiMAX subscriber identity
343630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            return true;
344630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else if (matchesMobile(ident)) {
3451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            switch (getNetworkClass(ident.mSubType)) {
3461b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                case NETWORK_CLASS_4_G:
3471b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    return true;
3481b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            }
3491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
3511b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3521b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3531b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
3541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     * Check if matches Wi-Fi network template.
3551b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3561b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesWifi(NetworkIdentity ident) {
3573ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey        switch (ident.mType) {
3583ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey            case TYPE_WIFI:
359e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                return Objects.equals(
3602e4dce0dd24aa89ca6adf6559f13d3e342ff8558Jeff Sharkey                        removeDoubleQuotes(mNetworkId), removeDoubleQuotes(ident.mNetworkId));
3613ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey            default:
3623ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey                return false;
3631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3651b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3664e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    /**
3674e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * Check if matches Ethernet network template.
3684e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     */
3694e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private boolean matchesEthernet(NetworkIdentity ident) {
3704e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        if (ident.mType == TYPE_ETHERNET) {
3714e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            return true;
3724e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        }
3734e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        return false;
3744e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
3754e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
376234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private boolean matchesMobileWildcard(NetworkIdentity ident) {
377234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
378234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            return true;
379234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        } else {
38070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey            return sForceAllNetworkTypes || contains(DATA_USAGE_NETWORK_TYPES, ident.mType);
381234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        }
382234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
383234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
384234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private boolean matchesWifiWildcard(NetworkIdentity ident) {
385234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        switch (ident.mType) {
386234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case TYPE_WIFI:
387234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case TYPE_WIFI_P2P:
388234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return true;
389234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            default:
390234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return false;
391234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        }
392234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
393234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
39455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    /**
39555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * Check if matches Bluetooth network template.
39655a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     */
39755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    private boolean matchesBluetooth(NetworkIdentity ident) {
39855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        if (ident.mType == TYPE_BLUETOOTH) {
39955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            return true;
40055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        }
40155a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        return false;
40255a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    }
40355a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
4044e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private static String getMatchRuleName(int matchRule) {
4051b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        switch (matchRule) {
4061b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_3G_LOWER:
4071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "MOBILE_3G_LOWER";
4081b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_4G:
4091b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "MOBILE_4G";
4101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_MOBILE_ALL:
4111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "MOBILE_ALL";
4121b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_WIFI:
4131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "WIFI";
4144e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            case MATCH_ETHERNET:
4154e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey                return "ETHERNET";
416234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
417234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return "MOBILE_WILDCARD";
418234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_WIFI_WILDCARD:
419234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return "WIFI_WILDCARD";
42055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            case MATCH_BLUETOOTH:
42155a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey                return "BLUETOOTH";
4221b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            default:
4231b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "UNKNOWN";
4241b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
4261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
427d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey    private static void ensureSubtypeAvailable() {
428d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        if (COMBINE_SUBTYPE_ENABLED) {
429d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey            throw new IllegalArgumentException(
430d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey                    "Unable to enforce 3G_LOWER template on combined data.");
431d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        }
432d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey    }
433d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey
4343256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    /**
4353256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Examine the given template and normalize if it refers to a "merged"
4363256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * mobile subscriber. We pick the "lowest" merged subscriber as the primary
4373256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * for key purposes, and expand the template to match all other merged
4383256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * subscribers.
4393256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * <p>
4403256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * For example, given an incoming template matching B, and the currently
4413256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * active merge set [A,B], we'd return a new template that primarily matches
4423256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * A, but also matches B.
4433256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     */
4443256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public static NetworkTemplate normalize(NetworkTemplate template, String[] merged) {
4453256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        if (template.isMatchRuleMobile() && ArrayUtils.contains(merged, template.mSubscriberId)) {
4463256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            // Requested template subscriber is part of the merge group; return
4473256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            // a template that matches all merged subscribers.
4483256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            return new NetworkTemplate(template.mMatchRule, merged[0], merged,
4493256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    template.mNetworkId);
4503256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        } else {
4513256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            return template;
4523256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
4533256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
4543256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
4551b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public static final Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
4568fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        @Override
4571b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        public NetworkTemplate createFromParcel(Parcel in) {
4581b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return new NetworkTemplate(in);
4591b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4601b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
4618fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        @Override
4621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        public NetworkTemplate[] newArray(int size) {
4631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return new NetworkTemplate[size];
4641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4651b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    };
466adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
467adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    public byte[] getBytesForBackup() throws IOException {
468adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        ByteArrayOutputStream baos = new ByteArrayOutputStream();
469adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        DataOutputStream out = new DataOutputStream(baos);
470adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
471adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        out.writeInt(BACKUP_VERSION);
472adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
473adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        out.writeInt(mMatchRule);
474adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        BackupUtils.writeString(out, mSubscriberId);
475adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        BackupUtils.writeString(out, mNetworkId);
476adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
477adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        return baos.toByteArray();
478adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    }
479adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
480adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    public static NetworkTemplate getNetworkTemplateFromBackup(DataInputStream in)
481adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy            throws IOException, BackupUtils.BadVersionException {
482adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        int version = in.readInt();
483adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        if (version < 1 || version > BACKUP_VERSION) {
484adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
485adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        }
486adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
487adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        int matchRule = in.readInt();
488adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        String subscriberId = BackupUtils.readString(in);
489adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        String networkId = BackupUtils.readString(in);
490adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
491adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        return new NetworkTemplate(matchRule, subscriberId, networkId);
492adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    }
4931b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey}
494