ConnectivityService.java revision aea743aaa43a833fd8ff3dc56205197583152d5f
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
191a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkeyimport static android.Manifest.permission.MANAGE_NETWORK_POLICY;
20c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.ConnectivityManager.isNetworkTypeValid;
21c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
22fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
23c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
2415c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganeshimport android.bluetooth.BluetoothTetheringDataTracker;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
29434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwaltimport android.database.ContentObserver;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.ConnectivityManager;
31da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwaltimport android.net.DummyDataStateTracker;
321997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.net.EthernetDataTracker;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.IConnectivityManager;
34c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.INetworkPolicyListener;
35c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.INetworkPolicyManager;
36c9822c5aeae833bb4a586c7af8a7b2641e8c17aeWink Savilleimport android.net.LinkAddress;
3715c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganeshimport android.net.LinkProperties;
380a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwaltimport android.net.LinkProperties.CompareResult;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.MobileDataStateTracker;
40d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwaltimport android.net.NetworkConfig;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.NetworkInfo;
42c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.NetworkInfo.DetailedState;
43f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkeyimport android.net.NetworkQuotaInfo;
44d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkState;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.NetworkStateTracker;
46585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport android.net.NetworkUtils;
47434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwaltimport android.net.Proxy;
48434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwaltimport android.net.ProxyProperties;
49aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport android.net.RouteInfo;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.wifi.WifiStateTracker;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
52da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwoodimport android.os.FileUtils;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
54bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Savilleimport android.os.HandlerThread;
5542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.os.IBinder;
56c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yehimport android.os.INetworkManagementService;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
59ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yehimport android.os.ParcelFileDescriptor;
6014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwaltimport android.os.PowerManager;
6142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.os.RemoteException;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings;
6542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.text.TextUtils;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog;
678a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
68c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.util.SparseIntArray;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
702e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yehimport com.android.internal.net.LegacyVpnInfo;
7104ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yehimport com.android.internal.net.VpnConfig;
7242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport com.android.internal.telephony.Phone;
73d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport com.android.server.connectivity.Tethering;
74ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yehimport com.android.server.connectivity.Vpn;
75ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
76d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport com.google.android.collect.Lists;
77fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport com.google.android.collect.Sets;
78d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
80d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriffimport java.io.IOException;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
82c9822c5aeae833bb4a586c7af8a7b2641e8c17aeWink Savilleimport java.net.Inet4Address;
83e822225f7a01ef088ff01f7613f953d5d89945edWink Savilleimport java.net.Inet6Address;
8447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.InetAddress;
8547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.UnknownHostException;
8642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport java.util.ArrayList;
87fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport java.util.Arrays;
8847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.util.Collection;
894e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwaltimport java.util.GregorianCalendar;
90fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport java.util.HashSet;
9142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport java.util.List;
92c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport java.util.concurrent.atomic.AtomicBoolean;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ConnectivityService extends IConnectivityManager.Stub {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
99ba175a5e1331883ef4ecfc2b751789a3492efca1Robert Greenwalt    private static final boolean DBG = true;
100e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private static final boolean VDBG = true;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "ConnectivityService";
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
103c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private static final boolean LOGD_RULES = false;
104c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
10542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // how long to wait before switching back to a radio's default network
10642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
10742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // system property that can override the above value
10842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
10942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            "android.telephony.apn-restore";
11042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
111f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    // used in recursive route setting to add gateways for the host for which
112f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    // a host route was requested.
113f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
114f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
115d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    private Tethering mTethering;
116c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt    private boolean mTetheringConfigValid = false;
117d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
118ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    private Vpn mVpn;
119ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
120fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    /** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
121fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private Object mRulesLock = new Object();
122c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    /** Currently active network rules by UID. */
123c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private SparseIntArray mUidRules = new SparseIntArray();
124fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    /** Set of ifaces that are costly. */
125fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private HashSet<String> mMeteredIfaces = Sets.newHashSet();
126c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sometimes we want to refer to the individual network state
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * trackers separately, and sometimes we just want to treat them
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * abstractly.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private NetworkStateTracker mNetTrackers[];
13342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
13442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    /**
135e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * The link properties that define the current links
136e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
137e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private LinkProperties mCurrentLinkProperties[];
138e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
139e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
14042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * A per Net list of the PID's that requested access to the net
14142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * used both as a refcount and for per-PID DNS selection
14242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     */
14342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private List mNetRequestersPids[];
14442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
14542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // priority order of the nettrackers
14642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // (excluding dynamically set mNetworkPreference)
14742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // TODO - move mNetworkTypePreference into this
14842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private int[] mPriorityList;
14942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context mContext;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mNetworkPreference;
15242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private int mActiveDefaultNetwork = -1;
153d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    // 0 is full bad, 100 is full good
154d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private int mDefaultInetCondition = 0;
155d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private int mDefaultInetConditionPublished = 0;
156d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private boolean mInetConditionChangeInFlight = false;
157d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private int mDefaultConnectionSequence = 0;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    private Object mDnsLock = new Object();
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mNumDnsEntries;
16144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    private boolean mDnsOverridden = false;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mTestMode;
16400092874b1fea2354b6a3048974abfc4bba69258Joe Onorato    private static ConnectivityService sServiceInstance;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
166d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt    private AtomicBoolean mBackgroundDataEnabled = new AtomicBoolean(true);
167d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt
16859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    private INetworkManagementService mNetd;
169c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private INetworkPolicyManager mPolicyManager;
17059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
1718dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int ENABLED  = 1;
1728dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int DISABLED = 0;
1738dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
1748dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    // Share the event space with NetworkStateTracker (which can't see this
1758dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    // internal class but sends us events).  If you change these, change
1768dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    // NetworkStateTracker.java too.
1778dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int MIN_NETWORK_STATE_TRACKER_EVENT = 1;
1788dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int MAX_NETWORK_STATE_TRACKER_EVENT = 100;
1798dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
1808dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
1818dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally as a delayed event to make us switch back to the
1828dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * default network
1838dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
1848dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_RESTORE_DEFAULT_NETWORK =
1858dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 1;
1868dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
1878dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
1888dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to change our mobile data enabled flag
1898dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
1908dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_CHANGE_MOBILE_DATA_ENABLED =
1918dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 2;
1928dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
1938dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
1948dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to change our network preference setting
1958dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = networkType to prefer
1968dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
1978dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_SET_NETWORK_PREFERENCE =
1988dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 3;
1998dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2008dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2018dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to synchronize inet condition reports
2028dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = networkType
2038dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg2 = condition (0 bad, 100 good)
2048dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2058dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_INET_CONDITION_CHANGE =
2068dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 4;
2078dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2088dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2098dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to mark the end of inet condition hold periods
2108dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = networkType
2118dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2128dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_INET_CONDITION_HOLD_END =
2138dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 5;
2148dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2158dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2168dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to set the background data preference
2178dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = TRUE for enabled, FALSE for disabled
2188dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2198dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_SET_BACKGROUND_DATA =
2208dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 6;
2218dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2228dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2238dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to set enable/disable cellular data
2248dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = ENBALED or DISABLED
2258dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2268dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_SET_MOBILE_DATA =
2278dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 7;
2288dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
229f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt    /**
230f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt     * used internally to clear a wakelock when transitioning
231f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt     * from one net to another
232f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt     */
233f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt    private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK =
234f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 8;
235f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt
236434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    /**
237434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt     * used internally to reload global proxy settings
238434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt     */
239434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY =
240434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 9;
241434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
242d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    /**
243d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     * used internally to set external dependency met/unmet
244d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     * arg1 = ENABLED (met) or DISABLED (unmet)
245d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     * arg2 = NetworkType
246d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     */
247d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    private static final int EVENT_SET_DEPENDENCY_MET =
248d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 10;
249d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt
25044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    /**
25144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh     * used internally to restore DNS properties back to the
25244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh     * default network
25344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh     */
25444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    private static final int EVENT_RESTORE_DNS =
25544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            MAX_NETWORK_STATE_TRACKER_EVENT + 11;
25644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
2572b30afdbad5e79c5775ac9756f3b986268d90f1fWink Saville    /**
258628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville     * used internally to send a sticky broadcast delayed.
259628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville     */
260628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private static final int EVENT_SEND_STICKY_BROADCAST_INTENT =
2612b30afdbad5e79c5775ac9756f3b986268d90f1fWink Saville            MAX_NETWORK_STATE_TRACKER_EVENT + 12;
262628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
26342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private Handler mHandler;
26442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
26542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // list of DeathRecipients used to make sure features are turned off when
26642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // a process dies
2673bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo    private List<FeatureUser> mFeatureUsers;
26842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
2690f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    private boolean mSystemReady;
2701c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn    private Intent mInitialBroadcast;
2710f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood
27214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private PowerManager.WakeLock mNetTransitionWakeLock;
27314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private String mNetTransitionWakeLockCausedBy = "";
27414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private int mNetTransitionWakeLockSerialNumber;
27514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private int mNetTransitionWakeLockTimeout;
27614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
277e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt    private InetAddress mDefaultDns;
278e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt
2790a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    // this collection is used to refcount the added routes - if there are none left
2800a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    // it's time to remove the route from the route table
2810a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private Collection<RouteInfo> mAddedRoutes = new ArrayList<RouteInfo>();
2820a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
2834e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt    // used in DBG mode to track inet condition reports
2844e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt    private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
2854e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt    private ArrayList mInetLog;
2864e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt
287434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    // track the current default http proxy - tell the world if we get a new one (real change)
288434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private ProxyProperties mDefaultProxy = null;
289434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    // track the global proxy.
290434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private ProxyProperties mGlobalProxy = null;
291434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private final Object mGlobalProxyLock = new Object();
292434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
293434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private SettingsObserver mSettingsObserver;
294434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
295d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    NetworkConfig[] mNetConfigs;
2965154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt    int mNetworksDefined;
29742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
298511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt    private static class RadioAttributes {
29942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public int mSimultaneity;
30042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public int mType;
30142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public RadioAttributes(String init) {
30242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            String fragments[] = init.split(",");
3035154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            mType = Integer.parseInt(fragments[0]);
3045154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            mSimultaneity = Integer.parseInt(fragments[1]);
30542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
30642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
30742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    RadioAttributes[] mRadioAttributes;
30842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
30950393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt    // the set of network types that can only be enabled by system/sig apps
31050393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt    List mProtectedNetworks;
31150393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
312c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    public ConnectivityService(
313c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            Context context, INetworkManagementService netd, INetworkPolicyManager policyManager) {
314ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("ConnectivityService starting up");
315de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt
316bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
317bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        handlerThread.start();
318bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        mHandler = new MyHandler(handlerThread.getLooper());
319bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville
320d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt        mBackgroundDataEnabled.set(Settings.Secure.getInt(context.getContentResolver(),
321d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt                Settings.Secure.BACKGROUND_DATA, 1) == 1);
322d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt
323de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt        // setup our unique device name
324733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt        if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
325733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt            String id = Settings.Secure.getString(context.getContentResolver(),
326733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt                    Settings.Secure.ANDROID_ID);
327733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt            if (id != null && id.length() > 0) {
328733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt                String name = new String("android_").concat(id);
329733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt                SystemProperties.set("net.hostname", name);
330733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt            }
331de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt        }
332de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt
333e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        // read our default dns server ip
334e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        String dns = Settings.Secure.getString(context.getContentResolver(),
335e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt                Settings.Secure.DEFAULT_DNS_SERVER);
336e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        if (dns == null || dns.length() == 0) {
337e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt            dns = context.getResources().getString(
338e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt                    com.android.internal.R.string.config_default_dns_server);
339e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        }
340e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        try {
341e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt            mDefaultDns = NetworkUtils.numericToInetAddress(dns);
342e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt        } catch (IllegalArgumentException e) {
343ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            loge("Error setting defaultDns using " + dns);
344e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        }
345e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt
346c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        mContext = checkNotNull(context, "missing Context");
347c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        mNetd = checkNotNull(netd, "missing INetworkManagementService");
348c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
34914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
350c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        try {
351c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            mPolicyManager.registerListener(mPolicyListener);
352c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        } catch (RemoteException e) {
353c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // ouch, no rules updates means some processes may never get network
35458d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            loge("unable to register INetworkPolicyListener" + e.toString());
355c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
356c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
357c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final PowerManager powerManager = (PowerManager) context.getSystemService(
358c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                Context.POWER_SERVICE);
35914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
36014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
36114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                com.android.internal.R.integer.config_networkTransitionTimeout);
36214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
36342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        mNetTrackers = new NetworkStateTracker[
36442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                ConnectivityManager.MAX_NETWORK_TYPE+1];
365e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
36686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNetworkPreference = getPersistedNetworkPreference();
36886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
3695154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mRadioAttributes = new RadioAttributes[ConnectivityManager.MAX_RADIO_TYPE+1];
370d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
3715154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt
37242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // Load device network attributes from resources
37342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String[] raStrings = context.getResources().getStringArray(
37442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                com.android.internal.R.array.radioAttributes);
3755154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (String raString : raStrings) {
3765154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            RadioAttributes r = new RadioAttributes(raString);
3775154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {
378ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);
3795154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                continue;
3805154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
3815154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (mRadioAttributes[r.mType] != null) {
382ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Error in radioAttributes - ignoring attempt to redefine type " +
3835154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                        r.mType);
3845154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                continue;
3855154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
38642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mRadioAttributes[r.mType] = r;
38742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
38842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
3895154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        String[] naStrings = context.getResources().getStringArray(
3905154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                com.android.internal.R.array.networkAttributes);
3915154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (String naString : naStrings) {
3925154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            try {
393d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                NetworkConfig n = new NetworkConfig(naString);
394975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
395ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    loge("Error in networkAttributes - ignoring attempt to define type " +
396975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            n.type);
3975154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    continue;
3985154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                }
399975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                if (mNetConfigs[n.type] != null) {
400ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    loge("Error in networkAttributes - ignoring attempt to redefine type " +
401975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            n.type);
4025154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    continue;
4035154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                }
404975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                if (mRadioAttributes[n.radio] == null) {
405ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    loge("Error in networkAttributes - ignoring attempt to use undefined " +
406975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            "radio " + n.radio + " in network type " + n.type);
4075154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    continue;
4085154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                }
409975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                mNetConfigs[n.type] = n;
4105154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                mNetworksDefined++;
4115154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            } catch(Exception e) {
4125154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                // ignore it - leave the entry null
4135154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
4145154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        }
4155154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt
41650393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        mProtectedNetworks = new ArrayList<Integer>();
41750393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        int[] protectedNetworks = context.getResources().getIntArray(
41850393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt                com.android.internal.R.array.config_protectedNetworks);
41950393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        for (int p : protectedNetworks) {
42050393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
42150393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt                mProtectedNetworks.add(p);
42250393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            } else {
42350393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt                if (DBG) loge("Ignoring protectedNetwork " + p);
42450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            }
42550393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        }
42650393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
42742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // high priority first
4285154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mPriorityList = new int[mNetworksDefined];
42942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        {
4305154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            int insertionPoint = mNetworksDefined-1;
4315154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            int currentLowest = 0;
4325154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            int nextLowest = 0;
4335154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            while (insertionPoint > -1) {
434d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                for (NetworkConfig na : mNetConfigs) {
4355154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    if (na == null) continue;
436975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                    if (na.priority < currentLowest) continue;
437975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                    if (na.priority > currentLowest) {
438975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        if (na.priority < nextLowest || nextLowest == 0) {
439975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            nextLowest = na.priority;
4405154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                        }
4415154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                        continue;
44242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
443975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                    mPriorityList[insertionPoint--] = na.type;
44442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
4455154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                currentLowest = nextLowest;
4465154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                nextLowest = 0;
44742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
44842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
44942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
4505154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mNetRequestersPids = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE+1];
4515154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (int i : mPriorityList) {
45242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mNetRequestersPids[i] = new ArrayList();
45342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
45442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
4553bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        mFeatureUsers = new ArrayList<FeatureUser>();
45642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
4575154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mNumDnsEntries = 0;
4585154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt
4595154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mTestMode = SystemProperties.get("cm.test.mode").equals("true")
4605154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                && SystemProperties.get("ro.build.type").equals("eng");
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Create the network state trackers for Wi-Fi and mobile
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * data. Maybe this could be done with a factory class,
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * but it's not clear that it's worth it, given that
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the number of different network types is not going
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * to change very often.
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4685154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (int netType : mPriorityList) {
469975c8488a3667efc24a1ad5da15d571d9615020fWink Saville            switch (mNetConfigs[netType].radio) {
4705154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            case ConnectivityManager.TYPE_WIFI:
471aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                mNetTrackers[netType] = new WifiStateTracker(netType,
472aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                        mNetConfigs[netType].name);
473aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                mNetTrackers[netType].startMonitoring(context, mHandler);
474aea743aaa43a833fd8ff3dc56205197583152d5frepo sync               break;
4755154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
476c7a98341b053bd8090accca151e8f3522f2dd126Wink Saville                mNetTrackers[netType] = new MobileDataStateTracker(netType,
477975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[netType].name);
478c7a98341b053bd8090accca151e8f3522f2dd126Wink Saville                mNetTrackers[netType].startMonitoring(context, mHandler);
4795154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                break;
480da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwalt            case ConnectivityManager.TYPE_DUMMY:
481da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwalt                mNetTrackers[netType] = new DummyDataStateTracker(netType,
482975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[netType].name);
483da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwalt                mNetTrackers[netType].startMonitoring(context, mHandler);
484da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwalt                break;
48515c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganesh            case ConnectivityManager.TYPE_BLUETOOTH:
48615c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganesh                mNetTrackers[netType] = BluetoothTetheringDataTracker.getInstance();
48715c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganesh                mNetTrackers[netType].startMonitoring(context, mHandler);
48815c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganesh                break;
4891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            case ConnectivityManager.TYPE_ETHERNET:
4901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                mNetTrackers[netType] = EthernetDataTracker.getInstance();
4911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                mNetTrackers[netType].startMonitoring(context, mHandler);
4921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                break;
4935154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            default:
494ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Trying to create a DataStateTracker for an unknown radio type " +
495975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[netType].radio);
4965154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                continue;
4975154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
4980a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            mCurrentLinkProperties[netType] = null;
499c96e6ccec9c41dee75f54e0db418df345e2a9bd9Robert Greenwalt            if (mNetConfigs[netType].isDefault()) mNetTrackers[netType].reconnect();
5005154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        }
501d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
502c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
503c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh        INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
504c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh
505c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh        mTethering = new Tethering(mContext, nmService, mHandler.getLooper());
506ccf83af1017b7b1eaf12f6ec3d2cb2137a7cdda9Robert Greenwalt        mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
5076fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                  mTethering.getTetherableWifiRegexs().length != 0 ||
5086fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                  mTethering.getTetherableBluetoothRegexs().length != 0) &&
509ccf83af1017b7b1eaf12f6ec3d2cb2137a7cdda9Robert Greenwalt                                 mTethering.getUpstreamIfaceTypes().length != 0);
510c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt
511ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        mVpn = new Vpn(mContext, new VpnCallback());
512ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
513008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh        try {
514008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh            nmService.registerObserver(mTethering);
515ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh            nmService.registerObserver(mVpn);
516008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh        } catch (RemoteException e) {
517008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh            loge("Error registering observer :" + e);
518008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh        }
519008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh
5204e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        if (DBG) {
5214e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            mInetLog = new ArrayList();
5224e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        }
523434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
524434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        mSettingsObserver = new SettingsObserver(mHandler, EVENT_APPLY_GLOBAL_HTTP_PROXY);
525434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        mSettingsObserver.observe(mContext);
526b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt
527b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        loadGlobalProxy();
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
53186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * Sets the preferred network.
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param preference the new preference
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5348dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    public void setNetworkPreference(int preference) {
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
5368dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
5378dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_NETWORK_PREFERENCE, preference, 0));
5388dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
5398dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
5408dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    public int getNetworkPreference() {
5418dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        enforceAccessPermission();
5428dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        int preference;
5438dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        synchronized(this) {
5448dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            preference = mNetworkPreference;
5458dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
5468dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        return preference;
5478dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
5488dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
5498dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleSetNetworkPreference(int preference) {
55042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (ConnectivityManager.isNetworkTypeValid(preference) &&
551d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                mNetConfigs[preference] != null &&
552d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                mNetConfigs[preference].isDefault()) {
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mNetworkPreference != preference) {
5548dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                final ContentResolver cr = mContext.getContentResolver();
5558dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                Settings.Secure.putInt(cr, Settings.Secure.NETWORK_PREFERENCE, preference);
5568dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                synchronized(this) {
5578dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    mNetworkPreference = preference;
5588dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enforcePreference();
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
564628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private int getConnectivityChangeDelay() {
565628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        final ContentResolver cr = mContext.getContentResolver();
566628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
567628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        /** Check system properties for the default value then use secure settings value, if any. */
568628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        int defaultDelay = SystemProperties.getInt(
569628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                "conn." + Settings.Secure.CONNECTIVITY_CHANGE_DELAY,
570628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                Settings.Secure.CONNECTIVITY_CHANGE_DELAY_DEFAULT);
571628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        return Settings.Secure.getInt(cr, Settings.Secure.CONNECTIVITY_CHANGE_DELAY,
572628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                defaultDelay);
573628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
574628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int getPersistedNetworkPreference() {
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ContentResolver cr = mContext.getContentResolver();
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int networkPrefSetting = Settings.Secure
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                .getInt(cr, Settings.Secure.NETWORK_PREFERENCE, -1);
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (networkPrefSetting != -1) {
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return networkPrefSetting;
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ConnectivityManager.DEFAULT_NETWORK_PREFERENCE;
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
58686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
58886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * Make the state of network connectivity conform to the preference settings
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * In this method, we only tear down a non-preferred network. Establishing
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a connection to the preferred network is taken care of when we handle
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the disconnect event from the non-preferred network
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (see {@link #handleDisconnect(NetworkInfo)}).
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enforcePreference() {
59542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (mNetTrackers[mNetworkPreference].getNetworkInfo().isConnected())
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (!mNetTrackers[mNetworkPreference].isAvailable())
59942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            return;
60042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
60142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        for (int t=0; t <= ConnectivityManager.MAX_RADIO_TYPE; t++) {
6025154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (t != mNetworkPreference && mNetTrackers[t] != null &&
60342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    mNetTrackers[t].getNetworkInfo().isConnected()) {
604ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt                if (DBG) {
605ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    log("tearing down " + mNetTrackers[t].getNetworkInfo() +
606ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt                            " in enforcePreference");
607ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt                }
60842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                teardown(mNetTrackers[t]);
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean teardown(NetworkStateTracker netTracker) {
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (netTracker.teardown()) {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            netTracker.setTeardownRequested(true);
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
623fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * Check if UID should be blocked from using the network represented by the
624fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * given {@link NetworkStateTracker}.
625c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey     */
626fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private boolean isNetworkBlocked(NetworkStateTracker tracker, int uid) {
627fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        final String iface = tracker.getLinkProperties().getInterfaceName();
628fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
629fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        final boolean networkCostly;
630fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        final int uidRules;
631fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        synchronized (mRulesLock) {
632fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            networkCostly = mMeteredIfaces.contains(iface);
633fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
634fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        }
635d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
636fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        if (networkCostly && (uidRules & RULE_REJECT_METERED) != 0) {
637fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            return true;
638c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
639fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
640fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        // no restrictive rules; network is visible
641fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        return false;
642c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
643c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
644c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    /**
645fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * Return a filtered {@link NetworkInfo}, potentially marked
646fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * {@link DetailedState#BLOCKED} based on
647fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * {@link #isNetworkBlocked(NetworkStateTracker, int)}.
648c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey     */
649fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private NetworkInfo getFilteredNetworkInfo(NetworkStateTracker tracker, int uid) {
650fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        NetworkInfo info = tracker.getNetworkInfo();
651fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        if (isNetworkBlocked(tracker, uid)) {
652d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // network is blocked; clone and override state
653d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            info = new NetworkInfo(info);
654d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            info.setDetailedState(DetailedState.BLOCKED, null, null);
655c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
656d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        return info;
657c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
658c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
659c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    /**
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return NetworkInfo for the active (i.e., connected) network interface.
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * It is assumed that at most one network is active at a time. If more
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * than one is active, it is indeterminate which will be returned.
66386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * @return the info for the active network, or {@code null} if none is
66486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * active
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
666c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NetworkInfo getActiveNetworkInfo() {
668c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        enforceAccessPermission();
669c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final int uid = Binder.getCallingUid();
670c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return getNetworkInfo(mActiveDefaultNetwork, uid);
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
673c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
674c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    public NetworkInfo getActiveNetworkInfoForUid(int uid) {
675c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        enforceConnectivityInternalPermission();
676c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return getNetworkInfo(mActiveDefaultNetwork, uid);
677c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
678c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
679c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NetworkInfo getNetworkInfo(int networkType) {
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceAccessPermission();
682c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final int uid = Binder.getCallingUid();
683c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return getNetworkInfo(networkType, uid);
684c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
685c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
686c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private NetworkInfo getNetworkInfo(int networkType, int uid) {
687c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        NetworkInfo info = null;
688c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        if (isNetworkTypeValid(networkType)) {
689c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[networkType];
690c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            if (tracker != null) {
691fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                info = getFilteredNetworkInfo(tracker, uid);
692c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
694c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return info;
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
697c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NetworkInfo[] getAllNetworkInfo() {
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceAccessPermission();
700c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final int uid = Binder.getCallingUid();
701d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final ArrayList<NetworkInfo> result = Lists.newArrayList();
702fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        synchronized (mRulesLock) {
703c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            for (NetworkStateTracker tracker : mNetTrackers) {
704c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                if (tracker != null) {
705fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                    result.add(getFilteredNetworkInfo(tracker, uid));
706c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                }
707c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
709d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        return result.toArray(new NetworkInfo[result.size()]);
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
712d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    /**
713d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * Return LinkProperties for the active (i.e., connected) default
714d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * network interface.  It is assumed that at most one default network
715d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * is active at a time. If more than one is active, it is indeterminate
716d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * which will be returned.
717d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * @return the ip properties for the active network, or {@code null} if
718d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * none is active
719d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     */
720c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
721d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    public LinkProperties getActiveLinkProperties() {
722599115894f6f960a879d2e3036c547bbf4136020Robert Greenwalt        return getLinkProperties(mActiveDefaultNetwork);
723d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    }
724d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt
725c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
726d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    public LinkProperties getLinkProperties(int networkType) {
727d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt        enforceAccessPermission();
728c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        if (isNetworkTypeValid(networkType)) {
729c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[networkType];
730c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            if (tracker != null) {
731c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                return tracker.getLinkProperties();
732c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
733d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt        }
734d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt        return null;
735d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    }
736d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt
737d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    @Override
738d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    public NetworkState[] getAllNetworkState() {
739d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        enforceAccessPermission();
740d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final int uid = Binder.getCallingUid();
741d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final ArrayList<NetworkState> result = Lists.newArrayList();
742fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        synchronized (mRulesLock) {
743d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            for (NetworkStateTracker tracker : mNetTrackers) {
744d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                if (tracker != null) {
745fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                    final NetworkInfo info = getFilteredNetworkInfo(tracker, uid);
746d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                    result.add(new NetworkState(
747d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                            info, tracker.getLinkProperties(), tracker.getLinkCapabilities()));
748d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                }
749d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            }
750d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        }
751d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        return result.toArray(new NetworkState[result.size()]);
752d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    }
753d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
754f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    private NetworkState getNetworkStateUnchecked(int networkType) {
755f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        if (isNetworkTypeValid(networkType)) {
756f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[networkType];
757f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            if (tracker != null) {
758f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey                return new NetworkState(tracker.getNetworkInfo(), tracker.getLinkProperties(),
759f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey                        tracker.getLinkCapabilities());
760f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            }
761f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        }
762f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        return null;
763f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    }
764f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey
765f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    @Override
766f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
767f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        enforceAccessPermission();
768f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
769f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        if (state != null) {
770f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            try {
771f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey                return mPolicyManager.getNetworkQuotaInfo(state);
772f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            } catch (RemoteException e) {
773f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            }
774f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        }
775f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        return null;
776f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    }
777f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setRadios(boolean turnOn) {
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean result = true;
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (NetworkStateTracker t : mNetTrackers) {
7825154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (t != null) result = t.setRadio(turnOn) && result;
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setRadio(int netType, boolean turnOn) {
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ConnectivityManager.isNetworkTypeValid(netType)) {
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NetworkStateTracker tracker = mNetTrackers[netType];
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return tracker != null && tracker.setRadio(turnOn);
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7969c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    /**
7979c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     * Used to notice when the calling process dies so we can self-expire
7989c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     *
7999c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     * Also used to know if the process has cleaned up after itself when
8009c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     * our auto-expire timer goes off.  The timer has a link to an object.
8019c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     *
8029c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     */
80342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private class FeatureUser implements IBinder.DeathRecipient {
80442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int mNetworkType;
80542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String mFeature;
80642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        IBinder mBinder;
80742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int mPid;
80842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int mUid;
809b928535902b204ac3ec25f161352786842248767Robert Greenwalt        long mCreateTime;
81042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
81142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        FeatureUser(int type, String feature, IBinder binder) {
81242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            super();
81342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mNetworkType = type;
81442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mFeature = feature;
81542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mBinder = binder;
81642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mPid = getCallingPid();
81742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mUid = getCallingUid();
818b928535902b204ac3ec25f161352786842248767Robert Greenwalt            mCreateTime = System.currentTimeMillis();
8199c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
82042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            try {
82142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                mBinder.linkToDeath(this, 0);
82242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } catch (RemoteException e) {
82342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                binderDied();
82442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
82542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
82642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
82742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        void unlinkDeathRecipient() {
82842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mBinder.unlinkToDeath(this, 0);
82942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
83042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
83142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public void binderDied() {
832ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("ConnectivityService FeatureUser binderDied(" +
833b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    mNetworkType + ", " + mFeature + ", " + mBinder + "), created " +
834b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    (System.currentTimeMillis() - mCreateTime) + " mSec ago");
8359c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            stopUsingNetworkFeature(this, false);
83642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
83742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
8389c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        public void expire() {
83958d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) {
84058d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                log("ConnectivityService FeatureUser expire(" +
84158d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                        mNetworkType + ", " + mFeature + ", " + mBinder +"), created " +
84258d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                        (System.currentTimeMillis() - mCreateTime) + " mSec ago");
84358d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            }
8449c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            stopUsingNetworkFeature(this, false);
8459c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
846b928535902b204ac3ec25f161352786842248767Robert Greenwalt
8473bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        public boolean isSameUser(FeatureUser u) {
8483bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            if (u == null) return false;
8493bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
8503bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            return isSameUser(u.mPid, u.mUid, u.mNetworkType, u.mFeature);
8513bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        }
8523bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
8533bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        public boolean isSameUser(int pid, int uid, int networkType, String feature) {
8543bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            if ((mPid == pid) && (mUid == uid) && (mNetworkType == networkType) &&
8553bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                TextUtils.equals(mFeature, feature)) {
8563bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                return true;
8573bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            }
8583bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            return false;
8593bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        }
8603bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
861b928535902b204ac3ec25f161352786842248767Robert Greenwalt        public String toString() {
862b928535902b204ac3ec25f161352786842248767Robert Greenwalt            return "FeatureUser("+mNetworkType+","+mFeature+","+mPid+","+mUid+"), created " +
863b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    (System.currentTimeMillis() - mCreateTime) + " mSec ago";
864b928535902b204ac3ec25f161352786842248767Robert Greenwalt        }
86542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
86642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
8679c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    // javadoc from interface
86842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    public int startUsingNetworkFeature(int networkType, String feature,
86942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            IBinder binder) {
87042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (DBG) {
871ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("startUsingNetworkFeature for net " + networkType + ": " + feature);
87242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
8745154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
875d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                mNetConfigs[networkType] == null) {
87642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            return Phone.APN_REQUEST_FAILED;
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
87842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
8799c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        FeatureUser f = new FeatureUser(networkType, feature, binder);
88042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
881aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        // TODO - move this into individual networktrackers
882aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
88350393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
88450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        if (mProtectedNetworks.contains(usedNetworkType)) {
88550393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            enforceConnectivityInternalPermission();
88650393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        }
88750393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
88842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        NetworkStateTracker network = mNetTrackers[usedNetworkType];
88942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (network != null) {
8900be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt            Integer currentPid = new Integer(getCallingPid());
89142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (usedNetworkType != networkType) {
89242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                NetworkInfo ni = network.getNetworkInfo();
89342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
89442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                if (ni.isAvailable() == false) {
895ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) log("special network not available");
896e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                    if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
897e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                        return Phone.APN_TYPE_NOT_AVAILABLE;
898e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                    } else {
899e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                        // else make the attempt anyway - probably giving REQUEST_STARTED below
900e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                    }
90142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
90242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
9033bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                int restoreTimer = getRestoreDefaultNetworkDelay(usedNetworkType);
9043bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
9059c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                synchronized(this) {
9063bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    boolean addToList = true;
9073bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    if (restoreTimer < 0) {
9083bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                        // In case there is no timer is specified for the feature,
9093bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                        // make sure we don't add duplicate entry with the same request.
9103bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                        for (FeatureUser u : mFeatureUsers) {
9113bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                            if (u.isSameUser(f)) {
9123bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                                // Duplicate user is found. Do not add.
9133bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                                addToList = false;
9143bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                                break;
9153bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                            }
9163bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                        }
9173bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    }
9183bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
9193bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    if (addToList) mFeatureUsers.add(f);
9209c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
9219c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                        // this gets used for per-pid dns when connected
9229c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                        mNetRequestersPids[usedNetworkType].add(currentPid);
9239c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    }
92442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
9259c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
926f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                if (restoreTimer >= 0) {
927f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                    mHandler.sendMessageDelayed(
928f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                            mHandler.obtainMessage(EVENT_RESTORE_DEFAULT_NETWORK, f), restoreTimer);
929f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                }
93042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
931a64bf834ffa677405af1c87c9f53eed0cd3853ceRobert Greenwalt                if ((ni.isConnectedOrConnecting() == true) &&
932a64bf834ffa677405af1c87c9f53eed0cd3853ceRobert Greenwalt                        !network.isTeardownRequested()) {
93342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    if (ni.isConnected() == true) {
93442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        // add the pid-specific dns
9358935696a19822283212591917f04e4b91b5b9219repo sync                        handleDnsConfigurationChange(usedNetworkType);
936ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        if (DBG) log("special network already active");
93742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return Phone.APN_ALREADY_ACTIVE;
93842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
939ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) log("special network already connecting");
94042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    return Phone.APN_REQUEST_STARTED;
94142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
94242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
94342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // check if the radio in play can make another contact
94442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // assume if cannot for now
94542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
946ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                if (DBG) log("reconnecting to special network");
94742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                network.reconnect();
94842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                return Phone.APN_REQUEST_STARTED;
94942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } else {
9500be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                // need to remember this unsupported request so we respond appropriately on stop
9510be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                synchronized(this) {
9520be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                    mFeatureUsers.add(f);
9530be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                    if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
9540be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                        // this gets used for per-pid dns when connected
9550be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                        mNetRequestersPids[usedNetworkType].add(currentPid);
9560be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                    }
9570be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                }
95802648a4b8422733ed401f07edf8e426318bb2f8dRobert Greenwalt                return -1;
95942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
96142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        return Phone.APN_TYPE_NOT_AVAILABLE;
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9649c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    // javadoc from interface
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int stopUsingNetworkFeature(int networkType, String feature) {
966b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt        enforceChangePermission();
967b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt
9689c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int pid = getCallingPid();
9699c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int uid = getCallingUid();
9709c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
9719c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        FeatureUser u = null;
9729c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        boolean found = false;
9739c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
9749c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        synchronized(this) {
9753bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            for (FeatureUser x : mFeatureUsers) {
9763bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                if (x.isSameUser(pid, uid, networkType, feature)) {
9773bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    u = x;
9789c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    found = true;
9799c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    break;
9809c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                }
9819c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            }
9829c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
9839c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        if (found && u != null) {
9849c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // stop regardless of how many other time this proc had called start
9859c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            return stopUsingNetworkFeature(u, true);
9869c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        } else {
9879c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // none found!
98858d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) log("ignoring stopUsingNetworkFeature - not a live request");
9899c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            return 1;
9909c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
99142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
99242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
9939c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    private int stopUsingNetworkFeature(FeatureUser u, boolean ignoreDups) {
9949c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int networkType = u.mNetworkType;
9959c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        String feature = u.mFeature;
9969c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int pid = u.mPid;
9979c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int uid = u.mUid;
9989c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
9999c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        NetworkStateTracker tracker = null;
10009c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        boolean callTeardown = false;  // used to carry our decision outside of sync block
10019c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
100242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (DBG) {
1003ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("stopUsingNetworkFeature for net " + networkType +
100442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    ": " + feature);
100542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
1006b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
101042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
10119c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        // need to link the mFeatureUsers list with the mNetRequestersPids state in this
10129c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        // sync block
10139c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        synchronized(this) {
10149c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // check if this process still has an outstanding start request
10159c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            if (!mFeatureUsers.contains(u)) {
1016ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                if (DBG) log("ignoring - this process has no outstanding requests");
10179c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                return 1;
10189c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            }
10199c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            u.unlinkDeathRecipient();
10209c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            mFeatureUsers.remove(mFeatureUsers.indexOf(u));
10219c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // If we care about duplicate requests, check for that here.
10229c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            //
10239c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // This is done to support the extension of a request - the app
10249c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // can request we start the network feature again and renew the
10259c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // auto-shutoff delay.  Normal "stop" calls from the app though
10269c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // do not pay attention to duplicate requests - in effect the
10279c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // API does not refcount and a single stop will counter multiple starts.
10289c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            if (ignoreDups == false) {
10293bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                for (FeatureUser x : mFeatureUsers) {
10303bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    if (x.isSameUser(u)) {
1031ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        if (DBG) log("ignoring stopUsingNetworkFeature as dup is found");
10329c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                        return 1;
10339c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    }
103442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
103542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
103642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1037aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            // TODO - move to individual network trackers
1038aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
1039aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
10409c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            tracker =  mNetTrackers[usedNetworkType];
10415154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (tracker == null) {
1042ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                if (DBG) log("ignoring - no known tracker for net type " + usedNetworkType);
10435154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                return -1;
10445154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
10455154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (usedNetworkType != networkType) {
10469c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                Integer currentPid = new Integer(pid);
10479c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                mNetRequestersPids[usedNetworkType].remove(currentPid);
1048421c72b6773582dd1473ace44c42d4e0ee1287e3Robert Greenwalt                reassessPidDns(pid, true);
10499c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                if (mNetRequestersPids[usedNetworkType].size() != 0) {
1050ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) log("not tearing down special network - " +
10519c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                           "others still using it");
10529c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    return 1;
10539c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                }
10549c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                callTeardown = true;
105519b9ab46a9faee6031aaf6c78748401943fea117Robert Greenwalt            } else {
105619b9ab46a9faee6031aaf6c78748401943fea117Robert Greenwalt                if (DBG) log("not a known feature - dropping");
105742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
10589c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
1059ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("Doing network teardown");
10609c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        if (callTeardown) {
106142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            tracker.teardown();
106242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            return 1;
106342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        } else {
106402648a4b8422733ed401f07edf8e426318bb2f8dRobert Greenwalt            return -1;
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1069585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @deprecated use requestRouteToHostAddress instead
1070585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     *
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ensure that a network route exists to deliver traffic to the specified
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * host via the specified network interface.
107386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * @param networkType the type of the network over which traffic to the
107486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * specified host is to be routed
107586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * @param hostAddress the IP address of the host to which the route is
107686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * desired
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} on success, {@code false} on failure
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean requestRouteToHost(int networkType, int hostAddress) {
1080585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
1081585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
1082585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        if (inetAddress == null) {
1083585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            return false;
1084585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        }
1085585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
1086585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        return requestRouteToHostAddress(networkType, inetAddress.getAddress());
1087585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    }
1088585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
1089585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    /**
1090585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * Ensure that a network route exists to deliver traffic to the specified
1091585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * host via the specified network interface.
1092585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param networkType the type of the network over which traffic to the
1093585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * specified host is to be routed
1094585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param hostAddress the IP address of the host to which the route is
1095585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * desired
1096585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @return {@code true} on success, {@code false} on failure
1097585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     */
1098585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
110050393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        if (mProtectedNetworks.contains(networkType)) {
110150393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            enforceConnectivityInternalPermission();
110250393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        }
110350393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NetworkStateTracker tracker = mNetTrackers[networkType];
11088206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt
11095154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        if (tracker == null || !tracker.getNetworkInfo().isConnected() ||
11105154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                tracker.isTeardownRequested()) {
111158d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) {
1112ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                log("requestRouteToHostAddress on down network " +
1113585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                           "(" + networkType + ") - dropped");
11148206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt            }
11158206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt            return false;
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
111747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        try {
1118585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            InetAddress addr = InetAddress.getByAddress(hostAddress);
11190a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            LinkProperties lp = tracker.getLinkProperties();
1120ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            return addRouteToAddress(lp, addr);
112147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        } catch (UnknownHostException e) {}
112247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        return false;
1123d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
1124d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
11250a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private boolean addRoute(LinkProperties p, RouteInfo r) {
11260a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return modifyRoute(p.getInterfaceName(), p, r, 0, true);
11270a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
1128d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
11290a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private boolean removeRoute(LinkProperties p, RouteInfo r) {
11300a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return modifyRoute(p.getInterfaceName(), p, r, 0, false);
11310a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
11320a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
1133ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
1134ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        return modifyRouteToAddress(lp, addr, true);
1135ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    }
1136ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt
1137ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
1138ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        return modifyRouteToAddress(lp, addr, false);
1139ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    }
1140ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt
1141ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) {
1142ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr);
1143ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        if (bestRoute == null) {
1144ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            bestRoute = RouteInfo.makeHostRoute(addr);
1145ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        } else {
1146ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (bestRoute.getGateway().equals(addr)) {
1147ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // if there is no better route, add the implied hostroute for our gateway
1148ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                bestRoute = RouteInfo.makeHostRoute(addr);
1149ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            } else {
1150ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // if we will connect to this through another route, add a direct route
1151ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // to it's gateway
1152ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway());
1153ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            }
1154ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        }
1155ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd);
1156ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    }
1157ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt
11580a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
11590a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            boolean doAdd) {
11600a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if ((ifaceName == null) || (lp == null) || (r == null)) return false;
11610a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
11620a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
11630a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            loge("Error adding route - too much recursion");
1164d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            return false;
1165d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1166f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
11670a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (r.isHostRoute() == false) {
11680a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), r.getGateway());
11690a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (bestRoute != null) {
1170476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                if (bestRoute.getGateway().equals(r.getGateway())) {
1171476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    // if there is no better route, add the implied hostroute for our gateway
11720a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    bestRoute = RouteInfo.makeHostRoute(r.getGateway());
1173476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                } else {
1174476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    // if we will connect to our gateway through another route, add a direct
1175476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    // route to it's gateway
1176476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
11770a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
1178476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd);
11790a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
1180f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
11810a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (doAdd) {
118258d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) log("Adding " + r + " for interface " + ifaceName);
11830a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            mAddedRoutes.add(r);
11840a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            try {
11850a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                mNetd.addRoute(ifaceName, r);
11860a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            } catch (Exception e) {
11870a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                // never crash - catch them all
118858d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                if (VDBG) loge("Exception trying to add a route: " + e);
1189f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                return false;
1190f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            }
11910a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        } else {
11920a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // if we remove this one and there are no more like it, then refcount==0 and
11930a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // we can remove it from the table
11940a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            mAddedRoutes.remove(r);
11950a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (mAddedRoutes.contains(r) == false) {
119658d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                if (VDBG) log("Removing " + r + " for interface " + ifaceName);
11970a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                try {
11980a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    mNetd.removeRoute(ifaceName, r);
11990a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                } catch (Exception e) {
12000a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    // never crash - catch them all
120158d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                    if (VDBG) loge("Exception trying to remove a route: " + e);
12020a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    return false;
12030a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
12040a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            } else {
120558d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                if (VDBG) log("not removing " + r + " as it's still in use");
12060a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
1207f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
12080a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return true;
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see ConnectivityManager#getBackgroundDataSetting()
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getBackgroundDataSetting() {
1215d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt        return mBackgroundDataEnabled.get();
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
121786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see ConnectivityManager#setBackgroundDataSetting(boolean)
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBackgroundDataSetting(boolean allowBackgroundDataUsage) {
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.enforceCallingOrSelfPermission(
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                android.Manifest.permission.CHANGE_BACKGROUND_DATA_SETTING,
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "ConnectivityService");
122586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
1226d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt        mBackgroundDataEnabled.set(allowBackgroundDataUsage);
1227d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt
12288dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_BACKGROUND_DATA,
12298dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                (allowBackgroundDataUsage ? ENABLED : DISABLED), 0));
12308dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
123186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
12328dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleSetBackgroundData(boolean enabled) {
1233db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt        Settings.Secure.putInt(mContext.getContentResolver(),
1234db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt                Settings.Secure.BACKGROUND_DATA, enabled ? 1 : 0);
1235db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt        Intent broadcast = new Intent(
1236db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt                ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
1237db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt        mContext.sendBroadcast(broadcast);
123886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt    }
123986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
1240c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    /**
1241c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     * @see ConnectivityManager#getMobileDataEnabled()
1242c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     */
1243c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    public boolean getMobileDataEnabled() {
1244e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        // TODO: This detail should probably be in DataConnectionTracker's
1245e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        //       which is where we store the value and maybe make this
1246e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        //       asynchronous.
1247c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        enforceAccessPermission();
1248c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        boolean retVal = Settings.Secure.getInt(mContext.getContentResolver(),
1249c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt                Settings.Secure.MOBILE_DATA, 1) == 1;
125058d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (VDBG) log("getMobileDataEnabled returning " + retVal);
1251c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        return retVal;
1252c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    }
1253c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt
1254d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    public void setDataDependency(int networkType, boolean met) {
125550393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        enforceConnectivityInternalPermission();
125650393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
1257d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_DEPENDENCY_MET,
1258d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                (met ? ENABLED : DISABLED), networkType));
1259d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    }
1260d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt
1261d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    private void handleSetDependencyMet(int networkType, boolean met) {
1262d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetTrackers[networkType] != null) {
1263d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (DBG) {
1264d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                log("handleSetDependencyMet(" + networkType + ", " + met + ")");
1265d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            }
1266d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            mNetTrackers[networkType].setDependencyMet(met);
1267d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        }
1268d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    }
1269d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt
1270c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
1271c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        @Override
1272fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        public void onUidRulesChanged(int uid, int uidRules) {
1273c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // only someone like NPMS should only be calling us
12741a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey            mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1275c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1276c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            if (LOGD_RULES) {
127758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
1278c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
1279c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1280fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            synchronized (mRulesLock) {
1281c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                // skip update when we've already applied rules
1282c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                final int oldRules = mUidRules.get(uid, RULE_ALLOW_ALL);
1283c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                if (oldRules == uidRules) return;
1284c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1285c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                mUidRules.put(uid, uidRules);
1286c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
1287c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1288c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // TODO: dispatch into NMS to push rules towards kernel module
1289c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // TODO: notify UID when it has requested targeted updates
1290c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
1291fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
1292fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        @Override
1293fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        public void onMeteredIfacesChanged(String[] meteredIfaces) {
1294fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            // only someone like NPMS should only be calling us
1295fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1296fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
1297fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            if (LOGD_RULES) {
129858d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
1299fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            }
1300fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
1301fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            synchronized (mRulesLock) {
1302fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                mMeteredIfaces.clear();
1303fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                for (String iface : meteredIfaces) {
1304fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                    mMeteredIfaces.add(iface);
1305fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                }
1306fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            }
1307fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        }
1308c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    };
1309c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1310c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    /**
1311c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     * @see ConnectivityManager#setMobileDataEnabled(boolean)
1312c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     */
13138dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    public void setMobileDataEnabled(boolean enabled) {
1314c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        enforceChangePermission();
1315ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("setMobileDataEnabled(" + enabled + ")");
1316c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt
13178dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA,
1318d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                (enabled ? ENABLED : DISABLED), 0));
13198dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
13208dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
13218dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleSetMobileData(boolean enabled) {
1322e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {
132358d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) {
132458d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                log(mNetTrackers[ConnectivityManager.TYPE_MOBILE].toString() + enabled);
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1326e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville            mNetTrackers[ConnectivityManager.TYPE_MOBILE].setDataEnable(enabled);
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enforceAccessPermission() {
133186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt        mContext.enforceCallingOrSelfPermission(
133286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                android.Manifest.permission.ACCESS_NETWORK_STATE,
133386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                "ConnectivityService");
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enforceChangePermission() {
133786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt        mContext.enforceCallingOrSelfPermission(
133886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                android.Manifest.permission.CHANGE_NETWORK_STATE,
133986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                "ConnectivityService");
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1342d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // TODO Make this a special check when it goes public
1343d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    private void enforceTetherChangePermission() {
1344d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        mContext.enforceCallingOrSelfPermission(
1345d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt                android.Manifest.permission.CHANGE_NETWORK_STATE,
1346d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt                "ConnectivityService");
1347d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
1348d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
13492a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    private void enforceTetherAccessPermission() {
13502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        mContext.enforceCallingOrSelfPermission(
13512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt                android.Manifest.permission.ACCESS_NETWORK_STATE,
13522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt                "ConnectivityService");
13532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
13542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
135514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private void enforceConnectivityInternalPermission() {
135614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mContext.enforceCallingOrSelfPermission(
135714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                android.Manifest.permission.CONNECTIVITY_INTERNAL,
135814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                "ConnectivityService");
135914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    }
136014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
136286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * Handle a {@code DISCONNECTED} event. If this pertains to the non-active
136386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * network, we ignore it. If it is for the active network, we send out a
136486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * broadcast. But first, we check whether it might be possible to connect
136586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * to a different network.
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info the {@code NetworkInfo} for the network
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleDisconnect(NetworkInfo info) {
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
137042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int prevNetType = info.getType();
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
137242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        mNetTrackers[prevNetType].setTeardownRequested(false);
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If the disconnected network is not the active one, then don't report
13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * this as a loss of connectivity. What probably happened is that we're
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * getting the disconnect for a network that we explicitly disabled
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * in accordance with network preference policies.
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1379d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (!mNetConfigs[prevNetType].isDefault()) {
138042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            List pids = mNetRequestersPids[prevNetType];
138142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            for (int i = 0; i<pids.size(); i++) {
138242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                Integer pid = (Integer)pids.get(i);
138342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // will remove them because the net's no longer connected
138442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // need to do this now as only now do we know the pids and
138542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // can properly null things that are no longer referenced.
138642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                reassessPidDns(pid.intValue(), false);
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.isFailover()) {
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            info.setFailover(false);
13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getReason() != null) {
13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getExtraInfo() != null) {
140086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
140186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    info.getExtraInfo());
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
140342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1404d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[prevNetType].isDefault()) {
1405f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            tryFailover(prevNetType);
1406f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            if (mActiveDefaultNetwork != -1) {
1407f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
1408cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
1409cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            } else {
1410029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt                mDefaultInetConditionPublished = 0; // we're not connected anymore
1411cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
1412cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            }
1413da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
1414029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
1415ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt
1416ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        // Reset interface if no other connections are using the same interface
1417ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        boolean doReset = true;
1418ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        LinkProperties linkProperties = mNetTrackers[prevNetType].getLinkProperties();
1419ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        if (linkProperties != null) {
1420ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            String oldIface = linkProperties.getInterfaceName();
1421ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            if (TextUtils.isEmpty(oldIface) == false) {
1422ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                for (NetworkStateTracker networkStateTracker : mNetTrackers) {
1423ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    if (networkStateTracker == null) continue;
1424ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    NetworkInfo networkInfo = networkStateTracker.getNetworkInfo();
1425ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    if (networkInfo.isConnected() && networkInfo.getType() != prevNetType) {
1426ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        LinkProperties l = networkStateTracker.getLinkProperties();
1427ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        if (l == null) continue;
1428ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        if (oldIface.equals(l.getInterfaceName())) {
1429ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                            doReset = false;
1430ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                            break;
1431ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        }
1432ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    }
1433ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                }
1434ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            }
1435ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        }
1436ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt
1437da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        // do this before we broadcast the change
1438ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        handleConnectivityChange(prevNetType, doReset);
1439da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt
1440628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
1441da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        /*
1442da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * If the failover network is already connected, then immediately send
1443da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * out a followup broadcast indicating successful failover
1444da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         */
1445f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt        if (mActiveDefaultNetwork != -1) {
1446628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            sendConnectedBroadcastDelayed(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo(),
1447628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    getConnectivityChangeDelay());
1448da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
1449da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt    }
1450da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt
1451f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt    private void tryFailover(int prevNetType) {
145242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        /*
1453bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt         * If this is a default network, check if other defaults are available.
1454bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt         * Try to reconnect on all available and let them hash it out when
1455bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt         * more than one connects.
145642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         */
1457d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[prevNetType].isDefault()) {
145842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (mActiveDefaultNetwork == prevNetType) {
145942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                mActiveDefaultNetwork = -1;
146042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
146142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1462f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            // don't signal a reconnect for anything lower or equal priority than our
1463f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            // current connected default
1464f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            // TODO - don't filter by priority now - nice optimization but risky
1465f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt//            int currentPriority = -1;
1466f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt//            if (mActiveDefaultNetwork != -1) {
1467d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt//                currentPriority = mNetConfigs[mActiveDefaultNetwork].mPriority;
1468f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt//            }
1469da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt            for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
14705154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                if (checkType == prevNetType) continue;
1471d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                if (mNetConfigs[checkType] == null) continue;
1472d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                if (!mNetConfigs[checkType].isDefault()) continue;
14739f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville
14749f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// Enabling the isAvailable() optimization caused mobile to not get
14759f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// selected if it was in the middle of error handling. Specifically
14769f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// a moble connection that took 30 seconds to complete the DEACTIVATE_DATA_CALL
14779f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// would not be available and we wouldn't get connected to anything.
14789f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// So removing the isAvailable() optimization below for now. TODO: This
14799f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// optimization should work and we need to investigate why it doesn't work.
14809f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// This could be related to how DEACTIVATE_DATA_CALL is reporting its
14819f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// complete before it is really complete.
14829f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville//                if (!mNetTrackers[checkType].isAvailable()) continue;
14839f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville
1484d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt//                if (currentPriority >= mNetConfigs[checkType].mPriority) continue;
1485bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt
1486f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkStateTracker checkTracker = mNetTrackers[checkType];
1487f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkInfo checkInfo = checkTracker.getNetworkInfo();
1488f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                if (!checkInfo.isConnectedOrConnecting() || checkTracker.isTeardownRequested()) {
1489f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                    checkInfo.setFailover(true);
1490f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                    checkTracker.reconnect();
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1492f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                if (DBG) log("Attempting to switch to " + checkInfo.getTypeName());
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void sendConnectedBroadcast(NetworkInfo info) {
14981e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt        sendGeneralBroadcast(info, ConnectivityManager.CONNECTIVITY_ACTION);
14991e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    }
15001e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt
1501628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private void sendConnectedBroadcastDelayed(NetworkInfo info, int delayMs) {
1502628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        sendGeneralBroadcastDelayed(info, ConnectivityManager.CONNECTIVITY_ACTION, delayMs);
1503628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
1504628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
15051e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    private void sendInetConditionBroadcast(NetworkInfo info) {
15061e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt        sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
15071e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    }
15081e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt
1509628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
15101e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt        Intent intent = new Intent(bcastType);
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.isFailover()) {
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            info.setFailover(false);
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getReason() != null) {
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getExtraInfo() != null) {
152086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
152186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    info.getExtraInfo());
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1523d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
1524628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        return intent;
1525628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
1526628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
1527628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
1528628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        sendStickyBroadcast(makeGeneralIntent(info, bcastType));
1529628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
1530628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
1531628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private void sendGeneralBroadcastDelayed(NetworkInfo info, String bcastType, int delayMs) {
1532628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        sendStickyBroadcastDelayed(makeGeneralIntent(info, bcastType), delayMs);
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when an attempt to fail over to another network has failed.
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info the {@link NetworkInfo} for the failed network
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleConnectionFailure(NetworkInfo info) {
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNetTrackers[info.getType()].setTeardownRequested(false);
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
154242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String reason = info.getReason();
154342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String extraInfo = info.getExtraInfo();
154442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1545572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt        String reasonText;
1546572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt        if (reason == null) {
1547572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt            reasonText = ".";
1548572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt        } else {
1549572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt            reasonText = " (" + reason + ").";
155042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
1551ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        loge("Attempt to connect to " + info.getTypeName() + " failed" + reasonText);
155286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
155342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
155442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
155542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (getActiveNetworkInfo() == null) {
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
155842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (reason != null) {
155942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_REASON, reason);
156042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
156142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (extraInfo != null) {
156242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, extraInfo);
156342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
156442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (info.isFailover()) {
156542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
156642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            info.setFailover(false);
156742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
1568da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt
1569d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[info.getType()].isDefault()) {
1570f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            tryFailover(info.getType());
1571f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            if (mActiveDefaultNetwork != -1) {
1572f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
1573cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
1574cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            } else {
1575029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt                mDefaultInetConditionPublished = 0;
1576cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
1577cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            }
1578da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
1579cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt
1580029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
15810f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        sendStickyBroadcast(intent);
1582da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        /*
1583da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * If the failover network is already connected, then immediately send
1584da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * out a followup broadcast indicating successful failover
1585da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         */
1586f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt        if (mActiveDefaultNetwork != -1) {
1587f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            sendConnectedBroadcast(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo());
1588da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
15890f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    }
15900f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood
15910f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    private void sendStickyBroadcast(Intent intent) {
15920f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        synchronized(this) {
15931c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            if (!mSystemReady) {
15941c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn                mInitialBroadcast = new Intent(intent);
15950f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood            }
15961c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1597628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            if (DBG) {
1598628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                log("sendStickyBroadcast: NetworkInfo=" +
1599628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO));
1600628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            }
1601628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
16021c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            mContext.sendStickyBroadcast(intent);
16030f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        }
16040f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    }
16050f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood
1606628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private void sendStickyBroadcastDelayed(Intent intent, int delayMs) {
1607628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        if (delayMs <= 0) {
1608628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            sendStickyBroadcast(intent);
1609628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        } else {
1610628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            if (DBG) log("sendStickyBroadcastDelayed: delayMs=" + delayMs + " intent=" + intent);
1611628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            mHandler.sendMessageDelayed(mHandler.obtainMessage(
1612628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    EVENT_SEND_STICKY_BROADCAST_INTENT, intent), delayMs);
1613628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        }
1614628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
1615628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
16160f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    void systemReady() {
16170f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        synchronized(this) {
16180f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood            mSystemReady = true;
16191c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            if (mInitialBroadcast != null) {
16201c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn                mContext.sendStickyBroadcast(mInitialBroadcast);
16211c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn                mInitialBroadcast = null;
16220f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood            }
16230f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        }
1624434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        // load the global proxy at startup
1625434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY));
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleConnect(NetworkInfo info) {
162942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int type = info.getType();
16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // snapshot isFailover, because sendConnectedBroadcast() resets it
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isFailover = info.isFailover();
163342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        NetworkStateTracker thisNet = mNetTrackers[type];
163442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
163542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // if this is a default net and other default is running
163642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // kill the one not preferred
1637d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[type].isDefault()) {
163842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
163942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                if ((type != mNetworkPreference &&
1640975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[mActiveDefaultNetwork].priority >
1641975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[type].priority) ||
164242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        mNetworkPreference == mActiveDefaultNetwork) {
164342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        // don't accept this one
164458d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                        if (VDBG) {
1645ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                            log("Not broadcasting CONNECT_ACTION " +
164642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                                "to torn down network " + info.getTypeName());
1647ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        }
164842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        teardown(thisNet);
164942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return;
165042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                } else {
165142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    // tear down the other
165242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    NetworkStateTracker otherNet =
165342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                            mNetTrackers[mActiveDefaultNetwork];
1654ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) {
1655ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        log("Policy requires " + otherNet.getNetworkInfo().getTypeName() +
165642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                            " teardown");
1657ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    }
165842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    if (!teardown(otherNet)) {
1659ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        loge("Network declined teardown request");
166027725e8cd1e2eb3b88186ae8d43e437f130b1f84Robert Greenwalt                        teardown(thisNet);
166142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return;
166242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
166314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                }
166414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            }
166514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            synchronized (ConnectivityService.this) {
166614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                // have a new default network, release the transition wakelock in a second
166714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                // if it's held.  The second pause is to allow apps to reconnect over the
166814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                // new network
166914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                if (mNetTransitionWakeLock.isHeld()) {
167014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    mHandler.sendMessageDelayed(mHandler.obtainMessage(
1671f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt                            EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
167214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            mNetTransitionWakeLockSerialNumber, 0),
167314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            1000);
167442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
167642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mActiveDefaultNetwork = type;
1677d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // this will cause us to come up initially as unconnected and switching
1678d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // to connected after our normal pause unless somebody reports us as reall
1679d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // disconnected
1680d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            mDefaultInetConditionPublished = 0;
1681d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            mDefaultConnectionSequence++;
1682d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            mInetConditionChangeInFlight = false;
1683d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // Don't do this - if we never sign in stay, grey
1684d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            //reportNetworkCondition(mActiveDefaultNetwork, 100);
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
168642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        thisNet.setTeardownRequested(false);
1687d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        updateNetworkSettings(thisNet);
1688ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        handleConnectivityChange(type, false);
1689628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1693c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * After a change in the connectivity state of a network. We're mainly
1694c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * concerned with making sure that the list of DNS servers is set up
1695c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * according to which networks are connected, and ensuring that the
1696c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * right routing table entries exist.
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1698ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt    private void handleConnectivityChange(int netType, boolean doReset) {
1699e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0;
1700e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
170242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         * If a non-default network is enabled, add the host routes that
1703c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt         * will allow it's DNS servers to be accessed.
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1705c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        handleDnsConfigurationChange(netType);
170642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
17070a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        LinkProperties curLp = mCurrentLinkProperties[netType];
17080a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        LinkProperties newLp = null;
17090a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
1710c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
17110a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            newLp = mNetTrackers[netType].getLinkProperties();
1712e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            if (VDBG) {
1713e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
1714e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        " doReset=" + doReset + " resetMask=" + resetMask +
1715e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        "\n   curLp=" + curLp +
1716e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        "\n   newLp=" + newLp);
1717e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            }
1718e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
17190a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (curLp != null) {
17200a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (curLp.isIdenticalInterfaceName(newLp)) {
17210a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    CompareResult<LinkAddress> car = curLp.compareAddresses(newLp);
17220a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    if ((car.removed.size() != 0) || (car.added.size() != 0)) {
17230a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        for (LinkAddress linkAddr : car.removed) {
17240a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            if (linkAddr.getAddress() instanceof Inet4Address) {
17250a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                resetMask |= NetworkUtils.RESET_IPV4_ADDRESSES;
17260a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            }
17270a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            if (linkAddr.getAddress() instanceof Inet6Address) {
17280a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                resetMask |= NetworkUtils.RESET_IPV6_ADDRESSES;
17290a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            }
1730e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        }
17310a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        if (DBG) {
17320a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            log("handleConnectivityChange: addresses changed" +
17330a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                    " linkProperty[" + netType + "]:" + " resetMask=" + resetMask +
17340a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                    "\n   car=" + car);
17350a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        }
17360a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    } else {
17370a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        if (DBG) {
17380a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            log("handleConnectivityChange: address are the same reset per doReset" +
17390a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                   " linkProperty[" + netType + "]:" +
17400a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                   " resetMask=" + resetMask);
1741e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        }
1742e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    }
1743e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                } else {
17440a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    resetMask = NetworkUtils.RESET_ALL_ADDRESSES;
174558d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                    if (DBG) {
174658d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                        log("handleConnectivityChange: interface not not equivalent reset both" +
174758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                                " linkProperty[" + netType + "]:" +
174858d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                                " resetMask=" + resetMask);
174958d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                    }
1750e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                }
1751e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            }
1752d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (mNetConfigs[netType].isDefault()) {
1753434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                handleApplyDefaultProxy(netType);
1754c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            }
1755c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        } else {
17560a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (VDBG) {
17570a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
17580a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        " doReset=" + doReset + " resetMask=" + resetMask +
17590a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        "\n  curLp=" + curLp +
17600a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        "\n  newLp= null");
176142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17630a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        mCurrentLinkProperties[netType] = newLp;
17640a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        updateRoutes(newLp, curLp, mNetConfigs[netType].isDefault());
1765ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt
1766e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        if (doReset || resetMask != 0) {
1767ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
1768ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            if (linkProperties != null) {
1769ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                String iface = linkProperties.getInterfaceName();
1770ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                if (TextUtils.isEmpty(iface) == false) {
1771e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    if (DBG) log("resetConnections(" + iface + ", " + resetMask + ")");
1772e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    NetworkUtils.resetConnections(iface, resetMask);
1773ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                }
1774ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            }
1775ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        }
17761ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo
17771ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        // TODO: Temporary notifying upstread change to Tethering.
17781ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        //       @see bug/4455071
17791ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        /** Notify TetheringService if interface name has been changed. */
17801ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
17811ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                             Phone.REASON_LINK_PROPERTIES_CHANGED)) {
17821ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo            if (isTetheringSupported()) {
17831ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                mTethering.handleTetherIfaceChange();
17841ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo            }
17851ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        }
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17880a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    /**
17890a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * Add and remove routes using the old properties (null if not previously connected),
17900a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * new properties (null if becoming disconnected).  May even be double null, which
17910a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * is a noop.
17920a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * Uses isLinkDefault to determine if default routes should be set or conversely if
17930a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * host routes should be set to the dns servers
17940a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     */
17950a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private void updateRoutes(LinkProperties newLp, LinkProperties curLp, boolean isLinkDefault) {
17960a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        Collection<RouteInfo> routesToAdd = null;
1797ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        CompareResult<InetAddress> dnsDiff = new CompareResult<InetAddress>();
1798ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
17990a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (curLp != null) {
18000a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // check for the delta between the current set and the new
1801ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            routeDiff = curLp.compareRoutes(newLp);
18020a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            dnsDiff = curLp.compareDnses(newLp);
1803ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        } else if (newLp != null) {
1804ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            routeDiff.added = newLp.getRoutes();
1805ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            dnsDiff.added = newLp.getDnses();
1806d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1807d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1808ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        for (RouteInfo r : routeDiff.removed) {
1809ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (isLinkDefault || ! r.isDefaultRoute()) {
1810ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                removeRoute(curLp, r);
1811d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
1812ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        }
181359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
1814ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        for (RouteInfo r :  routeDiff.added) {
1815ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (isLinkDefault || ! r.isDefaultRoute()) {
1816ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                addRoute(newLp, r);
181759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            }
1818d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1819d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
18200a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (!isLinkDefault) {
18210a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // handle DNS routes
1822ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (routeDiff.removed.size() == 0 && routeDiff.added.size() == 0) {
1823ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // no change in routes, check for change in dns themselves
1824ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                for (InetAddress oldDns : dnsDiff.removed) {
1825ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    removeRouteToAddress(curLp, oldDns);
1826edcb4f9d560a85970030e1df70426e8d1e2267d2Robert Greenwalt                }
1827ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                for (InetAddress newDns : dnsDiff.added) {
1828ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    addRouteToAddress(newLp, newDns);
182959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                }
1830ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            } else {
1831ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // routes changed - remove all old dns entries and add new
1832ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                if (curLp != null) {
1833ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    for (InetAddress oldDns : curLp.getDnses()) {
1834ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                        removeRouteToAddress(curLp, oldDns);
1835ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    }
1836ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                }
1837ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                if (newLp != null) {
1838ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    for (InetAddress newDns : newLp.getDnses()) {
1839ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                        addRouteToAddress(newLp, newDns);
1840ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    }
1841edcb4f9d560a85970030e1df70426e8d1e2267d2Robert Greenwalt                }
1842d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
1843d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1844d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
1845d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
18460a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
1847d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff   /**
1848d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * Reads the network specific TCP buffer sizes from SystemProperties
1849d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
1850d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * wide use
1851d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     */
1852d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff   public void updateNetworkSettings(NetworkStateTracker nt) {
1853d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        String key = nt.getTcpBufferSizesPropName();
1854d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        String bufferSizes = SystemProperties.get(key);
1855d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1856d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        if (bufferSizes.length() == 0) {
185758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) log(key + " not found in system properties. Using defaults");
1858d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1859d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            // Setting to default values so we won't be stuck to previous values
1860d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            key = "net.tcp.buffersize.default";
1861d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            bufferSizes = SystemProperties.get(key);
1862d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1863d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1864d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        // Set values in kernel
1865d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        if (bufferSizes.length() != 0) {
186658d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) {
1867ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                log("Setting TCP values: [" + bufferSizes
1868d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff                        + "] which comes from [" + key + "]");
1869d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
1870d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            setBufferSize(bufferSizes);
1871d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1872d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
1873d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1874d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff   /**
1875d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
1876d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
1877d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     *
1878d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * @param bufferSizes in the format of "readMin, readInitial, readMax,
1879d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     *        writeMin, writeInitial, writeMax"
1880d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     */
1881d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    private void setBufferSize(String bufferSizes) {
1882d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        try {
1883d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            String[] values = bufferSizes.split(",");
1884d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1885d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            if (values.length == 6) {
1886d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff              final String prefix = "/sys/kernel/ipv4/tcp_";
1887da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "rmem_min", values[0]);
1888da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "rmem_def", values[1]);
1889da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "rmem_max", values[2]);
1890da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "wmem_min", values[3]);
1891da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "wmem_def", values[4]);
1892da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "wmem_max", values[5]);
1893d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            } else {
1894ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Invalid buffersize string: " + bufferSizes);
1895d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
1896d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        } catch (IOException e) {
1897ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            loge("Can't set tcp buffer sizes:" + e);
1898d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1899d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
1900d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
190142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    /**
190242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * Adjust the per-process dns entries (net.dns<x>.<pid>) based
190342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * on the highest priority active net which this process requested.
190442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * If there aren't any, clear it out
190542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     */
190642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private void reassessPidDns(int myPid, boolean doBump)
190742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    {
190858d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (VDBG) log("reassessPidDns for pid " + myPid);
190942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        for(int i : mPriorityList) {
1910d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (mNetConfigs[i].isDefault()) {
191142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                continue;
191242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
191342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            NetworkStateTracker nt = mNetTrackers[i];
191442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (nt.getNetworkInfo().isConnected() &&
191542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    !nt.isTeardownRequested()) {
191637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                LinkProperties p = nt.getLinkProperties();
191747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                if (p == null) continue;
191842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                List pids = mNetRequestersPids[i];
191942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                for (int j=0; j<pids.size(); j++) {
192042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    Integer pid = (Integer)pids.get(j);
192142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    if (pid.intValue() == myPid) {
192247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                        Collection<InetAddress> dnses = p.getDnses();
192347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                        writePidDns(dnses, myPid);
192442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        if (doBump) {
192542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                            bumpDns();
192642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        }
192742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return;
192842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
192942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
193042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt           }
193142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
193242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // nothing found - delete
193342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        for (int i = 1; ; i++) {
193442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            String prop = "net.dns" + i + "." + myPid;
193542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (SystemProperties.get(prop).length() == 0) {
193642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                if (doBump) {
193742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    bumpDns();
193842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
193942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                return;
194042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
194142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            SystemProperties.set(prop, "");
194242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
194342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
194442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
19451039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt    // return true if results in a change
19461039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt    private boolean writePidDns(Collection <InetAddress> dnses, int pid) {
194742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int j = 1;
19481039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt        boolean changed = false;
194947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        for (InetAddress dns : dnses) {
19501039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            String dnsString = dns.getHostAddress();
19511039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            if (changed || !dnsString.equals(SystemProperties.get("net.dns" + j + "." + pid))) {
19521039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                changed = true;
19531039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                SystemProperties.set("net.dns" + j++ + "." + pid, dns.getHostAddress());
19541039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            }
195542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
19561039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt        return changed;
195742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
195842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
195942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private void bumpDns() {
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
196142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         * Bump the property that tells the name resolver library to reread
196242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         * the DNS server list from the properties.
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
196442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String propVal = SystemProperties.get("net.dnschange");
196542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int n = 0;
196642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (propVal.length() != 0) {
196742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            try {
196842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                n = Integer.parseInt(propVal);
196942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } catch (NumberFormatException e) {}
197042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
197142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        SystemProperties.set("net.dnschange", "" + (n+1));
197203595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        /*
197303595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt         * Tell the VMs to toss their DNS caches
197403595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt         */
197503595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        Intent intent = new Intent(Intent.ACTION_CLEAR_DNS_CACHE);
197603595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
19773d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt        /*
19783d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt         * Connectivity events can happen before boot has completed ...
19793d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt         */
19803d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
198103595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        mContext.sendBroadcast(intent);
198242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
198444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    // Caller must grab mDnsLock.
1985a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt    private boolean updateDns(String network, String iface,
1986a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            Collection<InetAddress> dnses, String domains) {
198744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        boolean changed = false;
198844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        int last = 0;
198944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        if (dnses.size() == 0 && mDefaultDns != null) {
199044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            ++last;
199144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            String value = mDefaultDns.getHostAddress();
199244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (!value.equals(SystemProperties.get("net.dns1"))) {
199344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                if (DBG) {
199458d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                    loge("no dns provided for " + network + " - using " + value);
199544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
199644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                changed = true;
199744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                SystemProperties.set("net.dns1", value);
199844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
199944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        } else {
200044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            for (InetAddress dns : dnses) {
200144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                ++last;
200244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                String key = "net.dns" + last;
200344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                String value = dns.getHostAddress();
200444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                if (!changed && value.equals(SystemProperties.get(key))) {
200544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    continue;
200644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
200758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                if (VDBG) {
200844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    log("adding dns " + value + " for " + network);
200944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
201044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                changed = true;
201144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                SystemProperties.set(key, value);
201244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
201344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        }
201444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        for (int i = last + 1; i <= mNumDnsEntries; ++i) {
201544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            String key = "net.dns" + i;
201658d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) log("erasing " + key);
201744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            changed = true;
201844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            SystemProperties.set(key, "");
201944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        }
202044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        mNumDnsEntries = last;
202144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
2022a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        if (changed) {
2023a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            try {
2024a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses));
2025a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                mNetd.setDefaultInterfaceForDns(iface);
2026a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            } catch (Exception e) {
202758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                loge("exception setting default dns interface: " + e);
2028a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            }
2029a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        }
203044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        if (!domains.equals(SystemProperties.get("net.dns.search"))) {
203144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            SystemProperties.set("net.dns.search", domains);
203244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            changed = true;
203344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        }
203444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        return changed;
203544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    }
203644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
2037c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt    private void handleDnsConfigurationChange(int netType) {
203842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // add default net's dns entries
2039c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        NetworkStateTracker nt = mNetTrackers[netType];
2040c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
204137e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt            LinkProperties p = nt.getLinkProperties();
2042c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            if (p == null) return;
2043c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            Collection<InetAddress> dnses = p.getDnses();
20441039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            boolean changed = false;
2045d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (mNetConfigs[netType].isDefault()) {
204644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                String network = nt.getNetworkInfo().getTypeName();
204744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                synchronized (mDnsLock) {
204844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    if (!mDnsOverridden) {
2049a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                        changed = updateDns(network, p.getInterfaceName(), dnses, "");
20501039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                    }
2051c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                }
2052c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            } else {
20531efe4d5cfd3913b3c4efa7aee4bf9fea262c0ad2Robert Greenwalt                try {
2054c59c6da9ae14097c77eee69285c6eacc8130936cRobert Greenwalt                    mNetd.setDnsServersForInterface(p.getInterfaceName(),
2055a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                            NetworkUtils.makeStrings(dnses));
20561efe4d5cfd3913b3c4efa7aee4bf9fea262c0ad2Robert Greenwalt                } catch (Exception e) {
205758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                    loge("exception setting dns servers: " + e);
2058c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                }
2059c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                // set per-pid dns for attached secondary nets
2060c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                List pids = mNetRequestersPids[netType];
2061c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                for (int y=0; y< pids.size(); y++) {
2062c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                    Integer pid = (Integer)pids.get(y);
20631039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                    changed = writePidDns(dnses, pid.intValue());
20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
20661039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            if (changed) bumpDns();
20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
206842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
206942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
2070f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt    private int getRestoreDefaultNetworkDelay(int networkType) {
207142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String restoreDefaultNetworkDelayStr = SystemProperties.get(
207242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                NETWORK_RESTORE_DELAY_PROP_NAME);
207342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if(restoreDefaultNetworkDelayStr != null &&
207442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                restoreDefaultNetworkDelayStr.length() != 0) {
207542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            try {
207642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                return Integer.valueOf(restoreDefaultNetworkDelayStr);
207742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } catch (NumberFormatException e) {
207842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2080f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        // if the system property isn't set, use the value for the apn type
2081f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        int ret = RESTORE_DEFAULT_NETWORK_DELAY;
2082f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt
2083f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) &&
2084f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                (mNetConfigs[networkType] != null)) {
2085f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt            ret = mNetConfigs[networkType].restoreTime;
2086f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        }
2087f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        return ret;
20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
209286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt        if (mContext.checkCallingOrSelfPermission(
209386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                android.Manifest.permission.DUMP)
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                != PackageManager.PERMISSION_GRANTED) {
209586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt            pw.println("Permission Denial: can't dump ConnectivityService " +
209686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    "from from pid=" + Binder.getCallingPid() + ", uid=" +
209786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    Binder.getCallingUid());
20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pw.println();
21019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (NetworkStateTracker nst : mNetTrackers) {
2102b928535902b204ac3ec25f161352786842248767Robert Greenwalt            if (nst != null) {
2103b928535902b204ac3ec25f161352786842248767Robert Greenwalt                if (nst.getNetworkInfo().isConnected()) {
2104b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    pw.println("Active network: " + nst.getNetworkInfo().
2105b928535902b204ac3ec25f161352786842248767Robert Greenwalt                            getTypeName());
2106b928535902b204ac3ec25f161352786842248767Robert Greenwalt                }
2107b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pw.println(nst.getNetworkInfo());
2108b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pw.println(nst);
2109b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pw.println();
2110b928535902b204ac3ec25f161352786842248767Robert Greenwalt            }
2111b928535902b204ac3ec25f161352786842248767Robert Greenwalt        }
2112b928535902b204ac3ec25f161352786842248767Robert Greenwalt
2113b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println("Network Requester Pids:");
2114b928535902b204ac3ec25f161352786842248767Robert Greenwalt        for (int net : mPriorityList) {
2115b928535902b204ac3ec25f161352786842248767Robert Greenwalt            String pidString = net + ": ";
2116b928535902b204ac3ec25f161352786842248767Robert Greenwalt            for (Object pid : mNetRequestersPids[net]) {
2117b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pidString = pidString + pid.toString() + ", ";
211842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
2119b928535902b204ac3ec25f161352786842248767Robert Greenwalt            pw.println(pidString);
21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2121b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println();
2122b928535902b204ac3ec25f161352786842248767Robert Greenwalt
2123b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println("FeatureUsers:");
2124b928535902b204ac3ec25f161352786842248767Robert Greenwalt        for (Object requester : mFeatureUsers) {
2125b928535902b204ac3ec25f161352786842248767Robert Greenwalt            pw.println(requester.toString());
2126b928535902b204ac3ec25f161352786842248767Robert Greenwalt        }
2127b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println();
21282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
212914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        synchronized (this) {
213014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            pw.println("NetworkTranstionWakeLock is currently " +
213114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
213214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
213314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        }
213414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        pw.println();
213514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
21362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        mTethering.dump(fd, pw, args);
21374e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt
21384e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        if (mInetLog != null) {
21394e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            pw.println();
21404e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            pw.println("Inet condition reports:");
21414e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            for(int i = 0; i < mInetLog.size(); i++) {
21424e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                pw.println(mInetLog.get(i));
21434e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            }
21444e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        }
21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
214742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // must be stateless - things change under us.
21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class MyHandler extends Handler {
2149bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        public MyHandler(Looper looper) {
2150bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville            super(looper);
2151bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        }
2152bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville
21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void handleMessage(Message msg) {
21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NetworkInfo info;
21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (msg.what) {
21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case NetworkStateTracker.EVENT_STATE_CHANGED:
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    info = (NetworkInfo) msg.obj;
2159511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    int type = info.getType();
2160511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    NetworkInfo.State state = info.getState();
2161511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt
2162ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) log("ConnectivityChange for " +
216386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                            info.getTypeName() + ": " +
2164511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                            state + "/" + info.getDetailedState());
21659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Connectivity state changed:
21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // [31-13] Reserved for future use
216886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    // [12-9] Network subtype (for mobile network, as defined
216986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    //         by TelephonyManager)
217086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    // [8-3] Detailed state ordinal (as defined by
217186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    //         NetworkInfo.DetailedState)
21729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // [2-0] Network type (as defined by ConnectivityManager)
21739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int eventLogParam = (info.getType() & 0x7) |
21749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ((info.getDetailedState().ordinal() & 0x3f) << 3) |
21759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (info.getSubtype() << 9);
2176ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker                    EventLog.writeEvent(EventLogTags.CONNECTIVITY_STATE_CHANGED,
217786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                            eventLogParam);
217886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
217986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    if (info.getDetailedState() ==
218086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                            NetworkInfo.DetailedState.FAILED) {
21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleConnectionFailure(info);
2182511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    } else if (state == NetworkInfo.State.DISCONNECTED) {
21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleDisconnect(info);
2184511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    } else if (state == NetworkInfo.State.SUSPENDED) {
21859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // TODO: need to think this over.
218686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // the logic here is, handle SUSPENDED the same as
218786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // DISCONNECTED. The only difference being we are
218886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // broadcasting an intent with NetworkInfo that's
218986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // suspended. This allows the applications an
219086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // opportunity to handle DISCONNECTED and SUSPENDED
219186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // differently, or not.
21929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleDisconnect(info);
2193511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    } else if (state == NetworkInfo.State.CONNECTED) {
21949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleConnect(info);
21959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
21969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
21979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED:
2198c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                    info = (NetworkInfo) msg.obj;
21991ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    // TODO: Temporary allowing network configuration
22001ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    //       change not resetting sockets.
22011ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    //       @see bug/4455071
22021ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    handleConnectivityChange(info.getType(), false);
22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
2204f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt                case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
220514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    String causedBy = null;
220614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    synchronized (ConnectivityService.this) {
220714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                        if (msg.arg1 == mNetTransitionWakeLockSerialNumber &&
220814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                                mNetTransitionWakeLock.isHeld()) {
220914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            mNetTransitionWakeLock.release();
221014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            causedBy = mNetTransitionWakeLockCausedBy;
221114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                        }
221214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    }
221314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    if (causedBy != null) {
2214ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        log("NetTransition Wakelock for " + causedBy + " released by timeout");
221514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    }
2216057d5e9824a01a03c13d5a32d3c7f5023d01586eRobert Greenwalt                    break;
22178dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_RESTORE_DEFAULT_NETWORK:
22189c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    FeatureUser u = (FeatureUser)msg.obj;
22199c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    u.expire();
2220d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                    break;
22218dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_INET_CONDITION_CHANGE:
22228dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
22238dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int netType = msg.arg1;
22248dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int condition = msg.arg2;
22258dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleInetConditionChange(netType, condition);
2226d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                    break;
22278dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
22288dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_INET_CONDITION_HOLD_END:
22298dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
22308dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int netType = msg.arg1;
22318dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int sequence = msg.arg2;
22328dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleInetConditionHoldEnd(netType, sequence);
2233d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                    break;
22348dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
22358dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_SET_NETWORK_PREFERENCE:
22368dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
22378dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int preference = msg.arg1;
22388dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleSetNetworkPreference(preference);
22398dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    break;
22408dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
22418dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_SET_BACKGROUND_DATA:
22428dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
22438dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    boolean enabled = (msg.arg1 == ENABLED);
22448dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleSetBackgroundData(enabled);
22458dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    break;
22468dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
22478dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_SET_MOBILE_DATA:
22488dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
22498dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    boolean enabled = (msg.arg1 == ENABLED);
22508dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleSetMobileData(enabled);
225114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    break;
22528dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
2253434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                case EVENT_APPLY_GLOBAL_HTTP_PROXY:
2254434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                {
2255434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    handleDeprecatedGlobalHttpProxy();
2256d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    break;
2257d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                }
2258d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                case EVENT_SET_DEPENDENCY_MET:
2259d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                {
2260d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    boolean met = (msg.arg1 == ENABLED);
2261d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    handleSetDependencyMet(msg.arg2, met);
2262d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    break;
2263434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                }
226444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                case EVENT_RESTORE_DNS:
226544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                {
226644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    if (mActiveDefaultNetwork != -1) {
226744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                        handleDnsConfigurationChange(mActiveDefaultNetwork);
226844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    }
226944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    break;
227044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
2271628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                case EVENT_SEND_STICKY_BROADCAST_INTENT:
2272628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                {
2273628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    Intent intent = (Intent)msg.obj;
2274628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    log("EVENT_SEND_STICKY_BROADCAST_INTENT: sendStickyBroadcast intent=" + intent);
2275628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    sendStickyBroadcast(intent);
2276628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    break;
2277628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                }
22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2281d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
2282d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // javadoc from interface
22835a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public int tether(String iface) {
2284d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        enforceTetherChangePermission();
22855a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
22865a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        if (isTetheringSupported()) {
22875a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return mTethering.tether(iface);
22885a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        } else {
22895a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
22905a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        }
2291d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
2292d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
2293d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // javadoc from interface
22945a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public int untether(String iface) {
2295d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        enforceTetherChangePermission();
22965a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
22975a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        if (isTetheringSupported()) {
22985a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return mTethering.untether(iface);
22995a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        } else {
23005a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
23015a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        }
23025a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    }
23035a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
23045a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    // javadoc from interface
23055a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public int getLastTetherError(String iface) {
23065a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        enforceTetherAccessPermission();
23075a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
23085a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        if (isTetheringSupported()) {
23095a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return mTethering.getLastTetherError(iface);
23105a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        } else {
23115a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
23125a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        }
23132a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
23142a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
23152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // TODO - proper iface API for selection by property, inspection, etc
23162a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    public String[] getTetherableUsbRegexs() {
23172a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
23182a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        if (isTetheringSupported()) {
23192a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return mTethering.getTetherableUsbRegexs();
23202a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        } else {
23212a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return new String[0];
23222a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        }
23232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
23242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
23252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    public String[] getTetherableWifiRegexs() {
23262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
23272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        if (isTetheringSupported()) {
23282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return mTethering.getTetherableWifiRegexs();
23292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        } else {
23302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return new String[0];
23316fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        }
23326fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    }
23336fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
23346fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    public String[] getTetherableBluetoothRegexs() {
23356fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        enforceTetherAccessPermission();
23366fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        if (isTetheringSupported()) {
23376fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang            return mTethering.getTetherableBluetoothRegexs();
23386fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        } else {
23396fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang            return new String[0];
23402a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        }
2341d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
2342d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
23436c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood    public int setUsbTethering(boolean enable) {
23446c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        enforceTetherAccessPermission();
23456c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        if (isTetheringSupported()) {
23466c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood            return mTethering.setUsbTethering(enable);
23476c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        } else {
23486c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
23496c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        }
23506c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood    }
23516c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood
2352d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // TODO - move iface listing, queries, etc to new module
2353d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // javadoc from interface
2354d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    public String[] getTetherableIfaces() {
23552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
2356d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        return mTethering.getTetherableIfaces();
2357d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
2358d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
2359d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    public String[] getTetheredIfaces() {
23602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
2361d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        return mTethering.getTetheredIfaces();
2362d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
23632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
23645a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public String[] getTetheringErroredIfaces() {
23655a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        enforceTetherAccessPermission();
23665a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        return mTethering.getErroredIfaces();
23675a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    }
23685a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
23692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // if ro.tether.denied = true we default to no tethering
23702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // gservices could set the secure setting to 1 though to enable it on a build where it
23712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // had previously been turned off.
23722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    public boolean isTetheringSupported() {
23732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
23742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
2375c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt        boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(),
2376c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt                Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0);
2377c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt        return tetherEnabledInSettings && mTetheringConfigValid;
23782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
237914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
238014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // An API NetworkStateTrackers can call when they lose their network.
238114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // This will automatically be cleared after X seconds or a network becomes CONNECTED,
238214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // whichever happens first.  The timer is started by the first caller and not
238314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // restarted by subsequent callers.
238414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    public void requestNetworkTransitionWakelock(String forWhom) {
238514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        enforceConnectivityInternalPermission();
238614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        synchronized (this) {
238714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            if (mNetTransitionWakeLock.isHeld()) return;
238814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            mNetTransitionWakeLockSerialNumber++;
238914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            mNetTransitionWakeLock.acquire();
239014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            mNetTransitionWakeLockCausedBy = forWhom;
239114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        }
239214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mHandler.sendMessageDelayed(mHandler.obtainMessage(
2393f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt                EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
239414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                mNetTransitionWakeLockSerialNumber, 0),
239514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                mNetTransitionWakeLockTimeout);
239614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        return;
239714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    }
2398ca4306c976d393c3cd04270bc2de0af2f4f30fa5Robert Greenwalt
2399d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    // 100 percent is full good, 0 is full bad.
2400d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    public void reportInetCondition(int networkType, int percentage) {
240158d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (VDBG) log("reportNetworkCondition(" + networkType + ", " + percentage + ")");
2402d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt        mContext.enforceCallingOrSelfPermission(
2403d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                android.Manifest.permission.STATUS_BAR,
2404d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                "ConnectivityService");
2405d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt
24064e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        if (DBG) {
24074e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            int pid = getCallingPid();
24084e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            int uid = getCallingUid();
24094e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            String s = pid + "(" + uid + ") reports inet is " +
24104e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                (percentage > 50 ? "connected" : "disconnected") + " (" + percentage + ") on " +
24114e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                "network Type " + networkType + " at " + GregorianCalendar.getInstance().getTime();
24124e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            mInetLog.add(s);
24134e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            while(mInetLog.size() > INET_CONDITION_LOG_MAX_SIZE) {
24144e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                mInetLog.remove(0);
24154e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            }
24164e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        }
2417d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(
24188dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            EVENT_INET_CONDITION_CHANGE, networkType, percentage));
24198dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
24208dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
24218dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleInetConditionChange(int netType, int condition) {
24228dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (DBG) {
2423ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("Inet connectivity change, net=" +
24248dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    netType + ", condition=" + condition +
24258dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    ",mActiveDefaultNetwork=" + mActiveDefaultNetwork);
24268dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24278dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mActiveDefaultNetwork == -1) {
2428ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("no active default network - aborting");
24298dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
24308dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24318dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mActiveDefaultNetwork != netType) {
2432ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("given net not default - aborting");
24338dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
24348dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24358dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mDefaultInetCondition = condition;
24368dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        int delay;
24378dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mInetConditionChangeInFlight == false) {
243858d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) log("starting a change hold");
24398dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            // setup a new hold to debounce this
24408dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            if (mDefaultInetCondition > 50) {
24418dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                delay = Settings.Secure.getInt(mContext.getContentResolver(),
24428dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                        Settings.Secure.INET_CONDITION_DEBOUNCE_UP_DELAY, 500);
24438dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            } else {
24448dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                delay = Settings.Secure.getInt(mContext.getContentResolver(),
24458dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                Settings.Secure.INET_CONDITION_DEBOUNCE_DOWN_DELAY, 3000);
24468dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            }
24478dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            mInetConditionChangeInFlight = true;
24488dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_INET_CONDITION_HOLD_END,
24498dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    mActiveDefaultNetwork, mDefaultConnectionSequence), delay);
24508dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        } else {
24518dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            // we've set the new condition, when this hold ends that will get
24528dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            // picked up
245358d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) log("currently in hold - not setting new end evt");
24548dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24558dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
24568dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
24578dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleInetConditionHoldEnd(int netType, int sequence) {
245858d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (VDBG) {
2459ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("Inet hold end, net=" + netType +
24608dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    ", condition =" + mDefaultInetCondition +
24618dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    ", published condition =" + mDefaultInetConditionPublished);
24628dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24638dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mInetConditionChangeInFlight = false;
24648dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
24658dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mActiveDefaultNetwork == -1) {
2466ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("no active default network - aborting");
24678dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
24688dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24698dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mDefaultConnectionSequence != sequence) {
2470ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("event hold for obsolete network - aborting");
24718dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
24728dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
2473628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        // TODO: Figure out why this optimization sometimes causes a
2474628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //       change in mDefaultInetCondition to be missed and the
2475628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //       UI to not be updated.
2476628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //if (mDefaultInetConditionPublished == mDefaultInetCondition) {
2477628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //    if (DBG) log("no change in condition - aborting");
2478628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //    return;
2479628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //}
24808dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        NetworkInfo networkInfo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
24818dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (networkInfo.isConnected() == false) {
2482ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("default network not connected - aborting");
24838dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
24848dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24858dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mDefaultInetConditionPublished = mDefaultInetCondition;
24868dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        sendInetConditionBroadcast(networkInfo);
24878dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        return;
2488d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    }
2489434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2490434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    public synchronized ProxyProperties getProxy() {
2491434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (mGlobalProxy != null) return mGlobalProxy;
2492434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (mDefaultProxy != null) return mDefaultProxy;
2493434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        return null;
2494434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2495434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2496434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    public void setGlobalProxy(ProxyProperties proxyProperties) {
2497434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        enforceChangePermission();
2498434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        synchronized (mGlobalProxyLock) {
2499434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (proxyProperties == mGlobalProxy) return;
2500434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
2501434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
2502434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2503434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String host = "";
2504434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            int port = 0;
2505434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String exclList = "";
2506434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (proxyProperties != null && !TextUtils.isEmpty(proxyProperties.getHost())) {
2507434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mGlobalProxy = new ProxyProperties(proxyProperties);
2508434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                host = mGlobalProxy.getHost();
2509434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                port = mGlobalProxy.getPort();
2510434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                exclList = mGlobalProxy.getExclusionList();
2511434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            } else {
2512434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mGlobalProxy = null;
2513434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            }
2514434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            ContentResolver res = mContext.getContentResolver();
2515434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            Settings.Secure.putString(res, Settings.Secure.GLOBAL_HTTP_PROXY_HOST, host);
2516434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            Settings.Secure.putInt(res, Settings.Secure.GLOBAL_HTTP_PROXY_PORT, port);
2517b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            Settings.Secure.putString(res, Settings.Secure.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
2518434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    exclList);
2519434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2520434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2521434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (mGlobalProxy == null) {
2522434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            proxyProperties = mDefaultProxy;
2523434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2524434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        sendProxyBroadcast(proxyProperties);
2525434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2526434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2527b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt    private void loadGlobalProxy() {
2528b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        ContentResolver res = mContext.getContentResolver();
2529b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        String host = Settings.Secure.getString(res, Settings.Secure.GLOBAL_HTTP_PROXY_HOST);
2530b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        int port = Settings.Secure.getInt(res, Settings.Secure.GLOBAL_HTTP_PROXY_PORT, 0);
2531b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        String exclList = Settings.Secure.getString(res,
2532b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt                Settings.Secure.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
2533b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        if (!TextUtils.isEmpty(host)) {
2534b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            ProxyProperties proxyProperties = new ProxyProperties(host, port, exclList);
2535b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            synchronized (mGlobalProxyLock) {
2536b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt                mGlobalProxy = proxyProperties;
2537b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            }
2538b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        }
2539b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt    }
2540b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt
2541434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    public ProxyProperties getGlobalProxy() {
2542434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        synchronized (mGlobalProxyLock) {
2543434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            return mGlobalProxy;
2544434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2545434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2546434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2547434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private void handleApplyDefaultProxy(int type) {
2548434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        // check if new default - push it out to all VM if so
2549434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        ProxyProperties proxy = mNetTrackers[type].getLinkProperties().getHttpProxy();
2550434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        synchronized (this) {
2551434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
2552434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (mDefaultProxy == proxy) return;
2553fde1eb7cf88e488d619d3168f83fb2e740d39296Robert Greenwalt            if (proxy != null && !TextUtils.isEmpty(proxy.getHost())) {
2554434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mDefaultProxy = proxy;
2555434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            } else {
2556434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mDefaultProxy = null;
2557434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            }
2558434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
255958d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (VDBG) log("changing default proxy to " + proxy);
2560434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if ((proxy == null && mGlobalProxy == null) || proxy.equals(mGlobalProxy)) return;
2561434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (mGlobalProxy != null) return;
2562434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        sendProxyBroadcast(proxy);
2563434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2564434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2565434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private void handleDeprecatedGlobalHttpProxy() {
2566434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        String proxy = Settings.Secure.getString(mContext.getContentResolver(),
2567434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                Settings.Secure.HTTP_PROXY);
2568434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (!TextUtils.isEmpty(proxy)) {
2569434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String data[] = proxy.split(":");
2570434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String proxyHost =  data[0];
2571434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            int proxyPort = 8080;
2572434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (data.length > 1) {
2573434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                try {
2574434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    proxyPort = Integer.parseInt(data[1]);
2575434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                } catch (NumberFormatException e) {
2576434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    return;
2577434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                }
2578434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            }
2579434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            ProxyProperties p = new ProxyProperties(data[0], proxyPort, "");
2580434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            setGlobalProxy(p);
2581434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2582434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2583434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2584434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private void sendProxyBroadcast(ProxyProperties proxy) {
258555985bed7be8c93296eee3f4f39557fba4fbaebeRobert Greenwalt        if (proxy == null) proxy = new ProxyProperties("", 0, "");
258658d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (DBG) log("sending Proxy Broadcast for " + proxy);
2587434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
2588b35d67a8a773f2d3127a119b424a86b3e56fe563Stan Chesnutt        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
2589b35d67a8a773f2d3127a119b424a86b3e56fe563Stan Chesnutt            Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2590434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
2591a2e13392412d5094e49ea0053599477401d1a67eRobert Greenwalt        mContext.sendStickyBroadcast(intent);
2592434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2593434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2594434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private static class SettingsObserver extends ContentObserver {
2595434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        private int mWhat;
2596434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        private Handler mHandler;
2597434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        SettingsObserver(Handler handler, int what) {
2598434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            super(handler);
2599434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            mHandler = handler;
2600434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            mWhat = what;
2601434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2602434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2603434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        void observe(Context context) {
2604434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            ContentResolver resolver = context.getContentResolver();
2605434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            resolver.registerContentObserver(Settings.Secure.getUriFor(
2606434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    Settings.Secure.HTTP_PROXY), false, this);
2607434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2608434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2609434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        @Override
2610434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        public void onChange(boolean selfChange) {
2611434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            mHandler.obtainMessage(mWhat).sendToTarget();
2612434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2613434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2614ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville
2615ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    private void log(String s) {
2616ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        Slog.d(TAG, s);
2617ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    }
2618ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville
2619ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    private void loge(String s) {
2620ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        Slog.e(TAG, s);
2621ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    }
2622ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
2623aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    int convertFeatureToNetworkType(int networkType, String feature) {
2624aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        int usedNetworkType = networkType;
2625aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
2626aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        if(networkType == ConnectivityManager.TYPE_MOBILE) {
2627aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
2628aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS;
2629aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
2630aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL;
2631aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
2632aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
2633aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN;
2634aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
2635aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
2636aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_FOTA)) {
2637aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_FOTA;
2638aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_IMS)) {
2639aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_IMS;
2640aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_CBS)) {
2641aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_CBS;
2642aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else {
2643aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                Slog.e(TAG, "Can't match any mobile netTracker!");
2644aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            }
2645aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } else if (networkType == ConnectivityManager.TYPE_WIFI) {
2646aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            if (TextUtils.equals(feature, "p2p")) {
2647aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_WIFI_P2P;
2648aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else {
2649aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                Slog.e(TAG, "Can't match any wifi netTracker!");
2650aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            }
2651aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } else {
2652aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            Slog.e(TAG, "Unexpected network type");
2653aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
2654aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        return usedNetworkType;
26552b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville    }
2656c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
2657c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private static <T> T checkNotNull(T value, String message) {
2658c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        if (value == null) {
2659c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            throw new NullPointerException(message);
2660c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
2661c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return value;
2662c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
2663ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
266404ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    /**
266504ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * Protect a socket from VPN routing rules. This method is used by
26662e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * VpnBuilder and not available in ConnectivityManager. Permissions
26672e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * are checked in Vpn class.
266804ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * @hide
266904ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     */
2670ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    @Override
26715779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh    public boolean protectVpn(ParcelFileDescriptor socket) {
26725779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        try {
26735779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            int type = mActiveDefaultNetwork;
26745779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            if (ConnectivityManager.isNetworkTypeValid(type)) {
26755779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                mVpn.protect(socket, mNetTrackers[type].getLinkProperties().getInterfaceName());
26765779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                return true;
26775779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            }
26785779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        } catch (Exception e) {
26795779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            // ignore
26805779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        } finally {
26815779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            try {
26825779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                socket.close();
26835779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            } catch (Exception e) {
26845779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                // ignore
26855779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            }
26865779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        }
26875779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        return false;
2688ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
2689ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
269004ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    /**
269104ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * Prepare for a VPN application. This method is used by VpnDialogs
26922e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * and not available in ConnectivityManager. Permissions are checked
26932e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * in Vpn class.
269404ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * @hide
269504ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     */
2696ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    @Override
2697100155a310fbb5028fc48e359bdfb7c4d3531843Chia-chi Yeh    public boolean prepareVpn(String oldPackage, String newPackage) {
2698100155a310fbb5028fc48e359bdfb7c4d3531843Chia-chi Yeh        return mVpn.prepare(oldPackage, newPackage);
2699ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
2700ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
270104ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    /**
270204ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * Configure a TUN interface and return its file descriptor. Parameters
270304ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * are encoded and opaque to this class. This method is used by VpnBuilder
27042e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * and not available in ConnectivityManager. Permissions are checked in
27052e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Vpn class.
270604ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * @hide
270704ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     */
2708ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    @Override
270904ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    public ParcelFileDescriptor establishVpn(VpnConfig config) {
2710ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        return mVpn.establish(config);
2711ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
2712ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
271377fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh    /**
27142e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Start legacy VPN and return an intent to VpnDialogs. This method is
27152e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * used by VpnSettings and not available in ConnectivityManager.
27162e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Permissions are checked in Vpn class.
27172e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * @hide
27182e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     */
27192e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    @Override
27202e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    public void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
27212e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh        mVpn.startLegacyVpn(config, racoon, mtpd);
27222e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    }
27232e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh
27242e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    /**
27252e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Return the information of the ongoing legacy VPN. This method is used
27262e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * by VpnSettings and not available in ConnectivityManager. Permissions
27272e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * are checked in Vpn class.
272877fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh     * @hide
272977fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh     */
273077fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh    @Override
27312e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    public LegacyVpnInfo getLegacyVpnInfo() {
27322e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh        return mVpn.getLegacyVpnInfo();
273377fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh    }
273477fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh
2735ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    /**
2736ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * Callback for VPN subsystem. Currently VPN is not adapted to the service
2737ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * through NetworkStateTracker since it works differently. For example, it
2738ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * needs to override DNS servers but never takes the default routes. It
2739ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * relies on another data network, and it could keep existing connections
2740ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * alive after reconnecting, switching between networks, or even resuming
2741ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * from deep sleep. Calls from applications should be done synchronously
2742ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * to avoid race conditions. As these are all hidden APIs, refactoring can
2743ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * be done whenever a better abstraction is developed.
2744ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     */
2745ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    public class VpnCallback {
2746ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
2747ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        private VpnCallback() {
2748ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        }
2749ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
275044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        public void override(List<String> dnsServers, List<String> searchDomains) {
275144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (dnsServers == null) {
275244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                restore();
275344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                return;
275444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
275544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
275644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // Convert DNS servers into addresses.
275744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            List<InetAddress> addresses = new ArrayList<InetAddress>();
275844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            for (String address : dnsServers) {
275944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                // Double check the addresses and remove invalid ones.
276044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                try {
276144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    addresses.add(InetAddress.parseNumericAddress(address));
276244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                } catch (Exception e) {
276344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    // ignore
276444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
276544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
276644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (addresses.isEmpty()) {
276744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                restore();
276844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                return;
276944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
277044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
277144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // Concatenate search domains into a string.
277244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            StringBuilder buffer = new StringBuilder();
277344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (searchDomains != null) {
277444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                for (String domain : searchDomains) {
277544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    buffer.append(domain).append(' ');
277644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
277744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
277844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            String domains = buffer.toString().trim();
277944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
278044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // Apply DNS changes.
278144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            boolean changed = false;
278244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            synchronized (mDnsLock) {
2783a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                changed = updateDns("VPN", "VPN", addresses, domains);
278444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                mDnsOverridden = true;
278544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
278644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (changed) {
278744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                bumpDns();
278844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
278944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
279044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // TODO: temporarily remove http proxy?
2791ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        }
2792ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
279344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        public void restore() {
279444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            synchronized (mDnsLock) {
279544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                if (!mDnsOverridden) {
279644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    return;
279744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
279844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                mDnsOverridden = false;
279944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
280044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
2801ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        }
2802ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
28039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2804