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;
2653ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colittiimport static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
2753ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colittiimport static android.net.NetworkStats.DEFAULT_NETWORK_NO;
2853ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colittiimport static android.net.NetworkStats.DEFAULT_NETWORK_YES;
2953ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colittiimport static android.net.NetworkStats.METERED_ALL;
3053ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colittiimport static android.net.NetworkStats.METERED_NO;
3153ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colittiimport static android.net.NetworkStats.METERED_YES;
3253ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colittiimport static android.net.NetworkStats.ROAMING_ALL;
3353ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colittiimport static android.net.NetworkStats.ROAMING_NO;
3453ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colittiimport static android.net.NetworkStats.ROAMING_YES;
352e4dce0dd24aa89ca6adf6559f13d3e342ff8558Jeff Sharkeyimport static android.net.wifi.WifiInfo.removeDoubleQuotes;
36adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.os.Parcel;
381b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.os.Parcelable;
39adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport android.util.BackupUtils;
403bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tateimport android.util.Log;
411b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
423256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkeyimport com.android.internal.util.ArrayUtils;
431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
44adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.ByteArrayOutputStream;
45adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.DataInputStream;
46adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.DataOutputStream;
47adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddyimport java.io.IOException;
483256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkeyimport java.util.Arrays;
4955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkeyimport java.util.Objects;
5055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
511b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey/**
52e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey * Predicate used to match {@link NetworkIdentity}, usually when collecting
53e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey * statistics. (It should probably have been named {@code NetworkPredicate}.)
541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey *
551b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * @hide
561b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */
571b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeypublic class NetworkTemplate implements Parcelable {
583bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate    private static final String TAG = "NetworkTemplate";
593bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
60adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    /**
61adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy     * Current Version of the Backup Serializer.
62adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy     */
63adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    private static final int BACKUP_VERSION = 1;
641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
65e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey    public static final int MATCH_MOBILE = 1;
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;
717f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    public static final int MATCH_PROXY = 9;
724e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
733bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate    private static boolean isKnownMatchRule(final int rule) {
743bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        switch (rule) {
75e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            case MATCH_MOBILE:
763bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_WIFI:
773bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_ETHERNET:
783bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_MOBILE_WILDCARD:
793bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_WIFI_WILDCARD:
803bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_BLUETOOTH:
813bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            case MATCH_PROXY:
823bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                return true;
833bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
843bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            default:
853bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                return false;
863bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        }
873bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate    }
883bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
8970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    private static boolean sForceAllNetworkTypes = false;
9070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
9170c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    public static void forceAllNetworkTypes() {
9270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        sForceAllNetworkTypes = true;
9370c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    }
9470c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
95630a1712168f402653039e368259cb9480454fa8Jeff Sharkey    /**
968fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
978fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * the given IMSI.
981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
994e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
100e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE, subscriberId, null);
1014e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1021b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
104234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks,
105234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     * regardless of IMSI.
106234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey     */
107234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public static NetworkTemplate buildTemplateMobileWildcard() {
108234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null);
109234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
110234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
111234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    /**
1128fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks,
1138fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * regardless of SSID.
1141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
1158fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public static NetworkTemplate buildTemplateWifiWildcard() {
116234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return new NetworkTemplate(MATCH_WIFI_WILDCARD, null, null);
1178fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
1188fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
1198fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Deprecated
1204e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateWifi() {
1218fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return buildTemplateWifiWildcard();
1228fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
1238fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
1248fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    /**
1258fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
1268fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     * given SSID.
1278fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey     */
1288fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public static NetworkTemplate buildTemplateWifi(String networkId) {
1298fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_WIFI, null, networkId);
1304e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
1324e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    /**
1334e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
1344e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * networks together.
1354e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     */
1364e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    public static NetworkTemplate buildTemplateEthernet() {
1378fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return new NetworkTemplate(MATCH_ETHERNET, null, null);
1384e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
1394e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
14055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    /**
14155a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * Template to combine all {@link ConnectivityManager#TYPE_BLUETOOTH} style
14255a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * networks together.
14355a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     */
14455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    public static NetworkTemplate buildTemplateBluetooth() {
14555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        return new NetworkTemplate(MATCH_BLUETOOTH, null, null);
14655a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    }
14755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
1487f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    /**
1497f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     * Template to combine all {@link ConnectivityManager#TYPE_PROXY} style
1507f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     * networks together.
1517f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     */
1527f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    public static NetworkTemplate buildTemplateProxy() {
1537f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati        return new NetworkTemplate(MATCH_PROXY, null, null);
1547f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    }
1557f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati
1564e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private final int mMatchRule;
1574e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private final String mSubscriberId;
1583256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1593256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    /**
1603256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Ugh, templates are designed to target a single subscriber, but we might
1613256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * need to match several "merged" subscribers. These are the subscribers
1623256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * that should be considered to match this template.
1633256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * <p>
1643256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Since the merge set is dynamic, it should <em>not</em> be persisted or
1653256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * used for determining equality.
1663256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     */
1673256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    private final String[] mMatchSubscriberIds;
1683256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1698fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    private final String mNetworkId;
1701b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
17153ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*.
17253ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    private final int mMetered;
17353ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    private final int mRoaming;
17453ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    private final int mDefaultNetwork;
17553ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti
1768fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
1773256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        this(matchRule, subscriberId, new String[] { subscriberId }, networkId);
1783256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
1793256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
1803256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
1813256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            String networkId) {
18253ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        this(matchRule, subscriberId, matchSubscriberIds, networkId, METERED_ALL, ROAMING_ALL,
18353ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti                DEFAULT_NETWORK_ALL);
18453ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    }
18553ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti
18653ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
18753ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            String networkId, int metered, int roaming, int defaultNetwork) {
1888fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mMatchRule = matchRule;
1898fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mSubscriberId = subscriberId;
1903256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        mMatchSubscriberIds = matchSubscriberIds;
1918fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mNetworkId = networkId;
19253ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        mMetered = metered;
19353ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        mRoaming = roaming;
19453ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        mDefaultNetwork = defaultNetwork;
1953bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
1963bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        if (!isKnownMatchRule(matchRule)) {
1973bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            Log.e(TAG, "Unknown network template rule " + matchRule
1983bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                    + " will not match any identity.");
1993bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        }
2001b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2011b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2024e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private NetworkTemplate(Parcel in) {
2031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mMatchRule = in.readInt();
2041b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mSubscriberId = in.readString();
2053256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        mMatchSubscriberIds = in.createStringArray();
2068fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        mNetworkId = in.readString();
20753ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        mMetered = in.readInt();
20853ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        mRoaming = in.readInt();
20953ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        mDefaultNetwork = in.readInt();
2101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2128fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Override
2131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public void writeToParcel(Parcel dest, int flags) {
2141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        dest.writeInt(mMatchRule);
2151b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        dest.writeString(mSubscriberId);
2163256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        dest.writeStringArray(mMatchSubscriberIds);
2178fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        dest.writeString(mNetworkId);
21853ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        dest.writeInt(mMetered);
21953ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        dest.writeInt(mRoaming);
22053ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        dest.writeInt(mDefaultNetwork);
2211b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2221b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2238fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    @Override
2241b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int describeContents() {
2251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return 0;
2261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2271b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2281b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public String toString() {
2308fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        final StringBuilder builder = new StringBuilder("NetworkTemplate: ");
2318fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        builder.append("matchRule=").append(getMatchRuleName(mMatchRule));
2328fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        if (mSubscriberId != null) {
2333256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            builder.append(", subscriberId=").append(
2343256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    NetworkIdentity.scrubSubscriberId(mSubscriberId));
2353256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
2363256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        if (mMatchSubscriberIds != null) {
2373256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            builder.append(", matchSubscriberIds=").append(
2383256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    Arrays.toString(NetworkIdentity.scrubSubscriberId(mMatchSubscriberIds)));
2398fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        }
2408fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        if (mNetworkId != null) {
2418fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey            builder.append(", networkId=").append(mNetworkId);
2428fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        }
24353ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        if (mMetered != METERED_ALL) {
24453ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            builder.append(", metered=").append(NetworkStats.meteredToString(mMetered));
24553ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        }
24653ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        if (mRoaming != ROAMING_ALL) {
24753ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            builder.append(", roaming=").append(NetworkStats.roamingToString(mRoaming));
24853ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        }
24953ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        if (mDefaultNetwork != DEFAULT_NETWORK_ALL) {
25053ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            builder.append(", defaultNetwork=").append(NetworkStats.defaultNetworkToString(
25153ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti                    mDefaultNetwork));
25253ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        }
2538fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return builder.toString();
2541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2551b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2561b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2571b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int hashCode() {
25853ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        return Objects.hash(mMatchRule, mSubscriberId, mNetworkId, mMetered, mRoaming,
25953ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti                mDefaultNetwork);
2601b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2611b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    @Override
2631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public boolean equals(Object obj) {
2641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        if (obj instanceof NetworkTemplate) {
2651b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            final NetworkTemplate other = (NetworkTemplate) obj;
2661b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return mMatchRule == other.mMatchRule
267e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                    && Objects.equals(mSubscriberId, other.mSubscriberId)
26853ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti                    && Objects.equals(mNetworkId, other.mNetworkId)
26953ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti                    && mMetered == other.mMetered
27053ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti                    && mRoaming == other.mRoaming
27153ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti                    && mDefaultNetwork == other.mDefaultNetwork;
2721b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
2731b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return false;
2741b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
2763256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public boolean isMatchRuleMobile() {
2773256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        switch (mMatchRule) {
278e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            case MATCH_MOBILE:
2793256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            case MATCH_MOBILE_WILDCARD:
2803256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                return true;
2813256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            default:
2823256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                return false;
2833256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
2843256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
2853256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
2867474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey    public boolean isPersistable() {
2877474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey        switch (mMatchRule) {
2887474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
2897474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            case MATCH_WIFI_WILDCARD:
2907474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey                return false;
2917474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey            default:
2927474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey                return true;
2937474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey        }
2947474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey    }
2957474fe7b421dcc190c4602389ca0f9c910382260Jeff Sharkey
2961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public int getMatchRule() {
2971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return mMatchRule;
2981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
2991b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3001b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public String getSubscriberId() {
3011b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        return mSubscriberId;
3021b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3048fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    public String getNetworkId() {
3058fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        return mNetworkId;
3068fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey    }
3078fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey
3081b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
309630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Test if given {@link NetworkIdentity} matches this template.
3101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public boolean matches(NetworkIdentity ident) {
31253ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        if (!matchesMetered(ident)) return false;
31353ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        if (!matchesRoaming(ident)) return false;
31453ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        if (!matchesDefaultNetwork(ident)) return false;
31553ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti
3161b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        switch (mMatchRule) {
317e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            case MATCH_MOBILE:
3181b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesMobile(ident);
3191b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_WIFI:
3201b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return matchesWifi(ident);
3214e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            case MATCH_ETHERNET:
3224e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey                return matchesEthernet(ident);
323234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
324234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return matchesMobileWildcard(ident);
325234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_WIFI_WILDCARD:
326234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return matchesWifiWildcard(ident);
32755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            case MATCH_BLUETOOTH:
32855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey                return matchesBluetooth(ident);
3297f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati            case MATCH_PROXY:
3307f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati                return matchesProxy(ident);
3311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            default:
3323bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                // We have no idea what kind of network template we are, so we
3333bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                // just claim not to match anything.
3343bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                return false;
3351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
33853ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    private boolean matchesMetered(NetworkIdentity ident) {
33953ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        return (mMetered == METERED_ALL)
34053ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            || (mMetered == METERED_YES && ident.mMetered)
34153ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            || (mMetered == METERED_NO && !ident.mMetered);
34253ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    }
34353ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti
34453ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    private boolean matchesRoaming(NetworkIdentity ident) {
34553ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        return (mRoaming == ROAMING_ALL)
34653ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            || (mRoaming == ROAMING_YES && ident.mRoaming)
34753ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            || (mRoaming == ROAMING_NO && !ident.mRoaming);
34853ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    }
34953ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti
35053ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    private boolean matchesDefaultNetwork(NetworkIdentity ident) {
35153ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti        return (mDefaultNetwork == DEFAULT_NETWORK_ALL)
35253ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            || (mDefaultNetwork == DEFAULT_NETWORK_YES && ident.mDefaultNetwork)
35353ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti            || (mDefaultNetwork == DEFAULT_NETWORK_NO && !ident.mDefaultNetwork);
35453ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti    }
35553ba2f0c12e816a08b0fb737ef651a340a5ed0a4Lorenzo Colitti
356f4de294297de47d8c594956b2d8607e314e71836Jeff Sharkey    public boolean matchesSubscriberId(String subscriberId) {
357f4de294297de47d8c594956b2d8607e314e71836Jeff Sharkey        return ArrayUtils.contains(mMatchSubscriberIds, subscriberId);
358f4de294297de47d8c594956b2d8607e314e71836Jeff Sharkey    }
359f4de294297de47d8c594956b2d8607e314e71836Jeff Sharkey
3601b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
361630a1712168f402653039e368259cb9480454fa8Jeff Sharkey     * Check if mobile network with matching IMSI.
3621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesMobile(NetworkIdentity ident) {
364630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
365630a1712168f402653039e368259cb9480454fa8Jeff Sharkey            // TODO: consider matching against WiMAX subscriber identity
3661b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return true;
367630a1712168f402653039e368259cb9480454fa8Jeff Sharkey        } else {
36866a6be3a4c955e52ea61e0d35f338983f632abf8Jack Yu            return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered))
36966a6be3a4c955e52ea61e0d35f338983f632abf8Jack Yu                    && !ArrayUtils.isEmpty(mMatchSubscriberIds)
37056859f323c1e7da9d537478e080d73614b207376Jeff Sharkey                    && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
3711b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3721b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3731b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3741b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
3751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     * Check if matches Wi-Fi network template.
3761b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     */
3771b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private boolean matchesWifi(NetworkIdentity ident) {
3783ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey        switch (ident.mType) {
3793ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey            case TYPE_WIFI:
380e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root                return Objects.equals(
3812e4dce0dd24aa89ca6adf6559f13d3e342ff8558Jeff Sharkey                        removeDoubleQuotes(mNetworkId), removeDoubleQuotes(ident.mNetworkId));
3823ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey            default:
3833ca7481439c9b65a137d7705d0f4a16766529e75Jeff Sharkey                return false;
3841b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
3851b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
3861b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
3874e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    /**
3884e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     * Check if matches Ethernet network template.
3894e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey     */
3904e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private boolean matchesEthernet(NetworkIdentity ident) {
3914e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        if (ident.mType == TYPE_ETHERNET) {
3924e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            return true;
3934e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        }
3944e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey        return false;
3954e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    }
3964e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey
397234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private boolean matchesMobileWildcard(NetworkIdentity ident) {
398234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        if (ident.mType == TYPE_WIMAX) {
399234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            return true;
400234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        } else {
40166a6be3a4c955e52ea61e0d35f338983f632abf8Jack Yu            return sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered);
402234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        }
403234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
404234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
405234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private boolean matchesWifiWildcard(NetworkIdentity ident) {
406234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        switch (ident.mType) {
407234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case TYPE_WIFI:
408234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case TYPE_WIFI_P2P:
409234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return true;
410234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            default:
411234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return false;
412234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        }
413234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
414234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
41555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    /**
41655a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     * Check if matches Bluetooth network template.
41755a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey     */
41855a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    private boolean matchesBluetooth(NetworkIdentity ident) {
41955a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        if (ident.mType == TYPE_BLUETOOTH) {
42055a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            return true;
42155a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        }
42255a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey        return false;
42355a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey    }
42455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey
4257f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    /**
4267f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     * Check if matches Proxy network template.
4277f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati     */
4287f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    private boolean matchesProxy(NetworkIdentity ident) {
4297f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati        return ident.mType == TYPE_PROXY;
4307f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati    }
4317f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati
4324e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey    private static String getMatchRuleName(int matchRule) {
4331b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        switch (matchRule) {
434e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            case MATCH_MOBILE:
435e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                return "MOBILE";
4361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            case MATCH_WIFI:
4371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                return "WIFI";
4384e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey            case MATCH_ETHERNET:
4394e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey                return "ETHERNET";
440234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_MOBILE_WILDCARD:
441234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return "MOBILE_WILDCARD";
442234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey            case MATCH_WIFI_WILDCARD:
443234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                return "WIFI_WILDCARD";
44455a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey            case MATCH_BLUETOOTH:
44555a442e58262e253df965d652bd8219c8d1e72d3Jeff Sharkey                return "BLUETOOTH";
4467f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati            case MATCH_PROXY:
4477f8d650ed75ce6f3934c62f971683fa806201e51Sharvil Nanavati                return "PROXY";
4481b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            default:
4493bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                return "UNKNOWN(" + matchRule + ")";
4501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4511b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    }
4521b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
4533256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    /**
4543256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * Examine the given template and normalize if it refers to a "merged"
4553256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * mobile subscriber. We pick the "lowest" merged subscriber as the primary
4563256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * for key purposes, and expand the template to match all other merged
4573256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * subscribers.
4583256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * <p>
4593256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * For example, given an incoming template matching B, and the currently
4603256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * active merge set [A,B], we'd return a new template that primarily matches
4613256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     * A, but also matches B.
4623256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey     */
4633256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    public static NetworkTemplate normalize(NetworkTemplate template, String[] merged) {
4643256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        if (template.isMatchRuleMobile() && ArrayUtils.contains(merged, template.mSubscriberId)) {
4653256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            // Requested template subscriber is part of the merge group; return
4663256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            // a template that matches all merged subscribers.
4673256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            return new NetworkTemplate(template.mMatchRule, merged[0], merged,
4683256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey                    template.mNetworkId);
4693256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        } else {
4703256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey            return template;
4713256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey        }
4723256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey    }
4733256601f5e4d94713f59e97b9d4912875c1bdcafJeff Sharkey
4741b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    public static final Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
4758fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        @Override
4761b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        public NetworkTemplate createFromParcel(Parcel in) {
4771b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return new NetworkTemplate(in);
4781b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4791b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
4808fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        @Override
4811b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        public NetworkTemplate[] newArray(int size) {
4821b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            return new NetworkTemplate[size];
4831b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        }
4841b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    };
485adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
486adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    public byte[] getBytesForBackup() throws IOException {
487adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        ByteArrayOutputStream baos = new ByteArrayOutputStream();
488adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        DataOutputStream out = new DataOutputStream(baos);
489adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
490adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        out.writeInt(BACKUP_VERSION);
491adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
492adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        out.writeInt(mMatchRule);
493adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        BackupUtils.writeString(out, mSubscriberId);
494adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        BackupUtils.writeString(out, mNetworkId);
495adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
496adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        return baos.toByteArray();
497adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    }
498adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
499adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    public static NetworkTemplate getNetworkTemplateFromBackup(DataInputStream in)
500adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy            throws IOException, BackupUtils.BadVersionException {
501adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        int version = in.readInt();
502adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        if (version < 1 || version > BACKUP_VERSION) {
503adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
504adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        }
505adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
506adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        int matchRule = in.readInt();
507adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        String subscriberId = BackupUtils.readString(in);
508adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        String networkId = BackupUtils.readString(in);
509adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy
5103bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        if (!isKnownMatchRule(matchRule)) {
5113bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate            throw new BackupUtils.BadVersionException(
5123bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate                    "Restored network template contains unknown match rule " + matchRule);
5133bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate        }
5143bf017325c26d868cfdc2e81ac303c5cd33196a9Christopher Tate
515adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy        return new NetworkTemplate(matchRule, subscriberId, networkId);
516adca34a0d6b5955f0cbc931dd0834b25fe3759b9Ritesh Reddy    }
5171b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey}
518