ConnectivityService.java revision c59c6da9ae14097c77eee69285c6eacc8130936c
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;
43d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkState;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.NetworkStateTracker;
45585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport android.net.NetworkUtils;
46434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwaltimport android.net.Proxy;
47434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwaltimport android.net.ProxyProperties;
48aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport android.net.RouteInfo;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.wifi.WifiStateTracker;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
51da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwoodimport android.os.FileUtils;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
53bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Savilleimport android.os.HandlerThread;
5442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.os.IBinder;
55c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yehimport android.os.INetworkManagementService;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
58ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yehimport android.os.ParcelFileDescriptor;
5914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwaltimport android.os.PowerManager;
6042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.os.RemoteException;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings;
6442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.text.TextUtils;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog;
668a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
67c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.util.SparseIntArray;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
692e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yehimport com.android.internal.net.LegacyVpnInfo;
7004ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yehimport com.android.internal.net.VpnConfig;
7142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport com.android.internal.telephony.Phone;
72d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport com.android.server.connectivity.Tethering;
73ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yehimport com.android.server.connectivity.Vpn;
74ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
75d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport com.google.android.collect.Lists;
76fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport com.google.android.collect.Sets;
77d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
79d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriffimport java.io.IOException;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
81c9822c5aeae833bb4a586c7af8a7b2641e8c17aeWink Savilleimport java.net.Inet4Address;
82e822225f7a01ef088ff01f7613f953d5d89945edWink Savilleimport java.net.Inet6Address;
8347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.InetAddress;
8447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.UnknownHostException;
8542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport java.util.ArrayList;
86fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport java.util.Arrays;
8747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.util.Collection;
884e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwaltimport java.util.GregorianCalendar;
89fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport java.util.HashSet;
9042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport java.util.List;
91c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport java.util.concurrent.atomic.AtomicBoolean;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ConnectivityService extends IConnectivityManager.Stub {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
98ba175a5e1331883ef4ecfc2b751789a3492efca1Robert Greenwalt    private static final boolean DBG = true;
99e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private static final boolean VDBG = true;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "ConnectivityService";
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
102c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private static final boolean LOGD_RULES = false;
103c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
10442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // how long to wait before switching back to a radio's default network
10542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
10642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // system property that can override the above value
10742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
10842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            "android.telephony.apn-restore";
10942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
110f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    // used in recursive route setting to add gateways for the host for which
111f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    // a host route was requested.
112f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
113f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
114d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    private Tethering mTethering;
115c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt    private boolean mTetheringConfigValid = false;
116d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
117ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    private Vpn mVpn;
118ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
119fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    /** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
120fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private Object mRulesLock = new Object();
121c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    /** Currently active network rules by UID. */
122c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private SparseIntArray mUidRules = new SparseIntArray();
123fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    /** Set of ifaces that are costly. */
124fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private HashSet<String> mMeteredIfaces = Sets.newHashSet();
125c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sometimes we want to refer to the individual network state
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * trackers separately, and sometimes we just want to treat them
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * abstractly.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private NetworkStateTracker mNetTrackers[];
13242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
13342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    /**
134e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * The link properties that define the current links
135e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
136e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private LinkProperties mCurrentLinkProperties[];
137e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
138e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
13942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * A per Net list of the PID's that requested access to the net
14042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * used both as a refcount and for per-PID DNS selection
14142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     */
14242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private List mNetRequestersPids[];
14342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
14442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // priority order of the nettrackers
14542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // (excluding dynamically set mNetworkPreference)
14642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // TODO - move mNetworkTypePreference into this
14742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private int[] mPriorityList;
14842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context mContext;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mNetworkPreference;
15142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private int mActiveDefaultNetwork = -1;
152d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    // 0 is full bad, 100 is full good
153d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private int mDefaultInetCondition = 0;
154d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private int mDefaultInetConditionPublished = 0;
155d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private boolean mInetConditionChangeInFlight = false;
156d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private int mDefaultConnectionSequence = 0;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    private Object mDnsLock = new Object();
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mNumDnsEntries;
16044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    private boolean mDnsOverridden = false;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mTestMode;
16300092874b1fea2354b6a3048974abfc4bba69258Joe Onorato    private static ConnectivityService sServiceInstance;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
165d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt    private AtomicBoolean mBackgroundDataEnabled = new AtomicBoolean(true);
166d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt
16759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    private INetworkManagementService mNetd;
168c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private INetworkPolicyManager mPolicyManager;
16959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
1708dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int ENABLED  = 1;
1718dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int DISABLED = 0;
1728dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
1738dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    // Share the event space with NetworkStateTracker (which can't see this
1748dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    // internal class but sends us events).  If you change these, change
1758dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    // NetworkStateTracker.java too.
1768dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int MIN_NETWORK_STATE_TRACKER_EVENT = 1;
1778dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int MAX_NETWORK_STATE_TRACKER_EVENT = 100;
1788dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
1798dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
1808dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally as a delayed event to make us switch back to the
1818dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * default network
1828dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
1838dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_RESTORE_DEFAULT_NETWORK =
1848dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 1;
1858dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
1868dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
1878dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to change our mobile data enabled flag
1888dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
1898dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_CHANGE_MOBILE_DATA_ENABLED =
1908dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 2;
1918dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
1928dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
1938dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to change our network preference setting
1948dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = networkType to prefer
1958dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
1968dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_SET_NETWORK_PREFERENCE =
1978dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 3;
1988dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
1998dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2008dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to synchronize inet condition reports
2018dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = networkType
2028dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg2 = condition (0 bad, 100 good)
2038dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2048dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_INET_CONDITION_CHANGE =
2058dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 4;
2068dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2078dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2088dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to mark the end of inet condition hold periods
2098dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = networkType
2108dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2118dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_INET_CONDITION_HOLD_END =
2128dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 5;
2138dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2148dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2158dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to set the background data preference
2168dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = TRUE for enabled, FALSE for disabled
2178dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2188dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_SET_BACKGROUND_DATA =
2198dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 6;
2208dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2218dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2228dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to set enable/disable cellular data
2238dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = ENBALED or DISABLED
2248dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2258dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int EVENT_SET_MOBILE_DATA =
2268dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 7;
2278dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
228f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt    /**
229f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt     * used internally to clear a wakelock when transitioning
230f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt     * from one net to another
231f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt     */
232f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt    private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK =
233f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 8;
234f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt
235434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    /**
236434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt     * used internally to reload global proxy settings
237434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt     */
238434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY =
239434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 9;
240434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
241d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    /**
242d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     * used internally to set external dependency met/unmet
243d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     * arg1 = ENABLED (met) or DISABLED (unmet)
244d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     * arg2 = NetworkType
245d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     */
246d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    private static final int EVENT_SET_DEPENDENCY_MET =
247d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            MAX_NETWORK_STATE_TRACKER_EVENT + 10;
248d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt
24944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    /**
25044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh     * used internally to restore DNS properties back to the
25144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh     * default network
25244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh     */
25344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    private static final int EVENT_RESTORE_DNS =
25444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            MAX_NETWORK_STATE_TRACKER_EVENT + 11;
25544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
25642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private Handler mHandler;
25742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
25842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // list of DeathRecipients used to make sure features are turned off when
25942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // a process dies
2603bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo    private List<FeatureUser> mFeatureUsers;
26142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
2620f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    private boolean mSystemReady;
2631c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn    private Intent mInitialBroadcast;
2640f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood
26514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private PowerManager.WakeLock mNetTransitionWakeLock;
26614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private String mNetTransitionWakeLockCausedBy = "";
26714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private int mNetTransitionWakeLockSerialNumber;
26814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private int mNetTransitionWakeLockTimeout;
26914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
270e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt    private InetAddress mDefaultDns;
271e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt
2720a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    // this collection is used to refcount the added routes - if there are none left
2730a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    // it's time to remove the route from the route table
2740a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private Collection<RouteInfo> mAddedRoutes = new ArrayList<RouteInfo>();
2750a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
2764e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt    // used in DBG mode to track inet condition reports
2774e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt    private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
2784e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt    private ArrayList mInetLog;
2794e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt
280434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    // track the current default http proxy - tell the world if we get a new one (real change)
281434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private ProxyProperties mDefaultProxy = null;
282434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    // track the global proxy.
283434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private ProxyProperties mGlobalProxy = null;
284434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private final Object mGlobalProxyLock = new Object();
285434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
286434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private SettingsObserver mSettingsObserver;
287434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
288d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    NetworkConfig[] mNetConfigs;
2895154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt    int mNetworksDefined;
29042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
291511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt    private static class RadioAttributes {
29242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public int mSimultaneity;
29342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public int mType;
29442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public RadioAttributes(String init) {
29542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            String fragments[] = init.split(",");
2965154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            mType = Integer.parseInt(fragments[0]);
2975154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            mSimultaneity = Integer.parseInt(fragments[1]);
29842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
29942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
30042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    RadioAttributes[] mRadioAttributes;
30142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
30250393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt    // the set of network types that can only be enabled by system/sig apps
30350393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt    List mProtectedNetworks;
30450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
305c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    public ConnectivityService(
306c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            Context context, INetworkManagementService netd, INetworkPolicyManager policyManager) {
307ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("ConnectivityService starting up");
308de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt
309bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
310bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        handlerThread.start();
311bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        mHandler = new MyHandler(handlerThread.getLooper());
312bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville
313d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt        mBackgroundDataEnabled.set(Settings.Secure.getInt(context.getContentResolver(),
314d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt                Settings.Secure.BACKGROUND_DATA, 1) == 1);
315d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt
316de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt        // setup our unique device name
317733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt        if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
318733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt            String id = Settings.Secure.getString(context.getContentResolver(),
319733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt                    Settings.Secure.ANDROID_ID);
320733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt            if (id != null && id.length() > 0) {
321733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt                String name = new String("android_").concat(id);
322733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt                SystemProperties.set("net.hostname", name);
323733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt            }
324de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt        }
325de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt
326e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        // read our default dns server ip
327e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        String dns = Settings.Secure.getString(context.getContentResolver(),
328e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt                Settings.Secure.DEFAULT_DNS_SERVER);
329e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        if (dns == null || dns.length() == 0) {
330e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt            dns = context.getResources().getString(
331e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt                    com.android.internal.R.string.config_default_dns_server);
332e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        }
333e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        try {
334e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt            mDefaultDns = NetworkUtils.numericToInetAddress(dns);
335e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt        } catch (IllegalArgumentException e) {
336ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            loge("Error setting defaultDns using " + dns);
337e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        }
338e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt
339c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        mContext = checkNotNull(context, "missing Context");
340c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        mNetd = checkNotNull(netd, "missing INetworkManagementService");
341c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
34214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
343c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        try {
344c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            mPolicyManager.registerListener(mPolicyListener);
345c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        } catch (RemoteException e) {
346c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // ouch, no rules updates means some processes may never get network
347c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            Slog.e(TAG, "unable to register INetworkPolicyListener", e);
348c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
349c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
350c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final PowerManager powerManager = (PowerManager) context.getSystemService(
351c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                Context.POWER_SERVICE);
35214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
35314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
35414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                com.android.internal.R.integer.config_networkTransitionTimeout);
35514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
35642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        mNetTrackers = new NetworkStateTracker[
35742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                ConnectivityManager.MAX_NETWORK_TYPE+1];
358e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
35986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNetworkPreference = getPersistedNetworkPreference();
36186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
3625154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mRadioAttributes = new RadioAttributes[ConnectivityManager.MAX_RADIO_TYPE+1];
363d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
3645154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt
36542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // Load device network attributes from resources
36642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String[] raStrings = context.getResources().getStringArray(
36742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                com.android.internal.R.array.radioAttributes);
3685154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (String raString : raStrings) {
3695154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            RadioAttributes r = new RadioAttributes(raString);
3705154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {
371ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);
3725154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                continue;
3735154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
3745154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (mRadioAttributes[r.mType] != null) {
375ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Error in radioAttributes - ignoring attempt to redefine type " +
3765154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                        r.mType);
3775154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                continue;
3785154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
37942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mRadioAttributes[r.mType] = r;
38042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
38142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
3825154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        String[] naStrings = context.getResources().getStringArray(
3835154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                com.android.internal.R.array.networkAttributes);
3845154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (String naString : naStrings) {
3855154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            try {
386d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                NetworkConfig n = new NetworkConfig(naString);
387975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
388ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    loge("Error in networkAttributes - ignoring attempt to define type " +
389975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            n.type);
3905154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    continue;
3915154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                }
392975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                if (mNetConfigs[n.type] != null) {
393ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    loge("Error in networkAttributes - ignoring attempt to redefine type " +
394975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            n.type);
3955154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    continue;
3965154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                }
397975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                if (mRadioAttributes[n.radio] == null) {
398ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    loge("Error in networkAttributes - ignoring attempt to use undefined " +
399975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            "radio " + n.radio + " in network type " + n.type);
4005154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    continue;
4015154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                }
402975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                mNetConfigs[n.type] = n;
4035154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                mNetworksDefined++;
4045154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            } catch(Exception e) {
4055154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                // ignore it - leave the entry null
4065154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
4075154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        }
4085154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt
40950393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        mProtectedNetworks = new ArrayList<Integer>();
41050393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        int[] protectedNetworks = context.getResources().getIntArray(
41150393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt                com.android.internal.R.array.config_protectedNetworks);
41250393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        for (int p : protectedNetworks) {
41350393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
41450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt                mProtectedNetworks.add(p);
41550393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            } else {
41650393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt                if (DBG) loge("Ignoring protectedNetwork " + p);
41750393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            }
41850393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        }
41950393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
42042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // high priority first
4215154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mPriorityList = new int[mNetworksDefined];
42242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        {
4235154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            int insertionPoint = mNetworksDefined-1;
4245154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            int currentLowest = 0;
4255154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            int nextLowest = 0;
4265154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            while (insertionPoint > -1) {
427d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                for (NetworkConfig na : mNetConfigs) {
4285154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    if (na == null) continue;
429975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                    if (na.priority < currentLowest) continue;
430975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                    if (na.priority > currentLowest) {
431975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        if (na.priority < nextLowest || nextLowest == 0) {
432975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            nextLowest = na.priority;
4335154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                        }
4345154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                        continue;
43542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
436975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                    mPriorityList[insertionPoint--] = na.type;
43742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
4385154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                currentLowest = nextLowest;
4395154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                nextLowest = 0;
44042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
44142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
44242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
4435154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mNetRequestersPids = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE+1];
4445154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (int i : mPriorityList) {
44542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mNetRequestersPids[i] = new ArrayList();
44642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
44742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
4483bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        mFeatureUsers = new ArrayList<FeatureUser>();
44942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
4505154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mNumDnsEntries = 0;
4515154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt
4525154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mTestMode = SystemProperties.get("cm.test.mode").equals("true")
4535154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                && SystemProperties.get("ro.build.type").equals("eng");
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Create the network state trackers for Wi-Fi and mobile
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * data. Maybe this could be done with a factory class,
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * but it's not clear that it's worth it, given that
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the number of different network types is not going
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * to change very often.
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4615154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (int netType : mPriorityList) {
462975c8488a3667efc24a1ad5da15d571d9615020fWink Saville            switch (mNetConfigs[netType].radio) {
4635154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            case ConnectivityManager.TYPE_WIFI:
464ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                if (DBG) log("Starting Wifi Service.");
465c7a98341b053bd8090accca151e8f3522f2dd126Wink Saville                WifiStateTracker wst = new WifiStateTracker();
4660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                WifiService wifiService = new WifiService(context);
4675154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
4680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff                wifiService.checkAndStartWifi();
4695154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;
470c7a98341b053bd8090accca151e8f3522f2dd126Wink Saville                wst.startMonitoring(context, mHandler);
4715154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                break;
4725154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            case ConnectivityManager.TYPE_MOBILE:
473c7a98341b053bd8090accca151e8f3522f2dd126Wink Saville                mNetTrackers[netType] = new MobileDataStateTracker(netType,
474975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[netType].name);
475c7a98341b053bd8090accca151e8f3522f2dd126Wink Saville                mNetTrackers[netType].startMonitoring(context, mHandler);
4765154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                break;
477da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwalt            case ConnectivityManager.TYPE_DUMMY:
478da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwalt                mNetTrackers[netType] = new DummyDataStateTracker(netType,
479975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[netType].name);
480da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwalt                mNetTrackers[netType].startMonitoring(context, mHandler);
481da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwalt                break;
48215c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganesh            case ConnectivityManager.TYPE_BLUETOOTH:
48315c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganesh                mNetTrackers[netType] = BluetoothTetheringDataTracker.getInstance();
48415c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganesh                mNetTrackers[netType].startMonitoring(context, mHandler);
48515c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganesh                break;
4861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            case ConnectivityManager.TYPE_ETHERNET:
4871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                mNetTrackers[netType] = EthernetDataTracker.getInstance();
4881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                mNetTrackers[netType].startMonitoring(context, mHandler);
4891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                break;
4905154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            default:
491ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Trying to create a DataStateTracker for an unknown radio type " +
492975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[netType].radio);
4935154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                continue;
4945154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
4950a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            mCurrentLinkProperties[netType] = null;
496c96e6ccec9c41dee75f54e0db418df345e2a9bd9Robert Greenwalt            if (mNetConfigs[netType].isDefault()) mNetTrackers[netType].reconnect();
4975154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        }
498d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
499c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
500c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh        INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
501c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh
502c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yeh        mTethering = new Tethering(mContext, nmService, mHandler.getLooper());
503ccf83af1017b7b1eaf12f6ec3d2cb2137a7cdda9Robert Greenwalt        mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
5046fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                  mTethering.getTetherableWifiRegexs().length != 0 ||
5056fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                  mTethering.getTetherableBluetoothRegexs().length != 0) &&
506ccf83af1017b7b1eaf12f6ec3d2cb2137a7cdda9Robert Greenwalt                                 mTethering.getUpstreamIfaceTypes().length != 0);
507c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt
508ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        mVpn = new Vpn(mContext, new VpnCallback());
509ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
510008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh        try {
511008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh            nmService.registerObserver(mTethering);
512ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh            nmService.registerObserver(mVpn);
513008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh        } catch (RemoteException e) {
514008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh            loge("Error registering observer :" + e);
515008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh        }
516008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh
5174e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        if (DBG) {
5184e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            mInetLog = new ArrayList();
5194e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        }
520434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
521434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        mSettingsObserver = new SettingsObserver(mHandler, EVENT_APPLY_GLOBAL_HTTP_PROXY);
522434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        mSettingsObserver.observe(mContext);
523b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt
524b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        loadGlobalProxy();
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
52886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * Sets the preferred network.
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param preference the new preference
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5318dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    public void setNetworkPreference(int preference) {
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
5338dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
5348dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_NETWORK_PREFERENCE, preference, 0));
5358dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
5368dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
5378dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    public int getNetworkPreference() {
5388dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        enforceAccessPermission();
5398dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        int preference;
5408dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        synchronized(this) {
5418dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            preference = mNetworkPreference;
5428dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
5438dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        return preference;
5448dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
5458dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
5468dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleSetNetworkPreference(int preference) {
54742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (ConnectivityManager.isNetworkTypeValid(preference) &&
548d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                mNetConfigs[preference] != null &&
549d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                mNetConfigs[preference].isDefault()) {
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mNetworkPreference != preference) {
5518dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                final ContentResolver cr = mContext.getContentResolver();
5528dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                Settings.Secure.putInt(cr, Settings.Secure.NETWORK_PREFERENCE, preference);
5538dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                synchronized(this) {
5548dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    mNetworkPreference = preference;
5558dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enforcePreference();
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int getPersistedNetworkPreference() {
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ContentResolver cr = mContext.getContentResolver();
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int networkPrefSetting = Settings.Secure
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                .getInt(cr, Settings.Secure.NETWORK_PREFERENCE, -1);
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (networkPrefSetting != -1) {
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return networkPrefSetting;
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ConnectivityManager.DEFAULT_NETWORK_PREFERENCE;
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
57286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
57486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * Make the state of network connectivity conform to the preference settings
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * In this method, we only tear down a non-preferred network. Establishing
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a connection to the preferred network is taken care of when we handle
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the disconnect event from the non-preferred network
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (see {@link #handleDisconnect(NetworkInfo)}).
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enforcePreference() {
58142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (mNetTrackers[mNetworkPreference].getNetworkInfo().isConnected())
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (!mNetTrackers[mNetworkPreference].isAvailable())
58542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            return;
58642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
58742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        for (int t=0; t <= ConnectivityManager.MAX_RADIO_TYPE; t++) {
5885154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (t != mNetworkPreference && mNetTrackers[t] != null &&
58942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    mNetTrackers[t].getNetworkInfo().isConnected()) {
590ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt                if (DBG) {
591ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    log("tearing down " + mNetTrackers[t].getNetworkInfo() +
592ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt                            " in enforcePreference");
593ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt                }
59442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                teardown(mNetTrackers[t]);
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean teardown(NetworkStateTracker netTracker) {
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (netTracker.teardown()) {
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            netTracker.setTeardownRequested(true);
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
609fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * Check if UID should be blocked from using the network represented by the
610fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * given {@link NetworkStateTracker}.
611c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey     */
612fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private boolean isNetworkBlocked(NetworkStateTracker tracker, int uid) {
613fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        final String iface = tracker.getLinkProperties().getInterfaceName();
614fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
615fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        final boolean networkCostly;
616fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        final int uidRules;
617fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        synchronized (mRulesLock) {
618fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            networkCostly = mMeteredIfaces.contains(iface);
619fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
620fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        }
621d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
622fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        if (networkCostly && (uidRules & RULE_REJECT_METERED) != 0) {
623fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            return true;
624c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
625fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
626fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        // no restrictive rules; network is visible
627fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        return false;
628c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
629c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
630c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    /**
631fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * Return a filtered {@link NetworkInfo}, potentially marked
632fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * {@link DetailedState#BLOCKED} based on
633fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * {@link #isNetworkBlocked(NetworkStateTracker, int)}.
634c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey     */
635fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private NetworkInfo getFilteredNetworkInfo(NetworkStateTracker tracker, int uid) {
636fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        NetworkInfo info = tracker.getNetworkInfo();
637fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        if (isNetworkBlocked(tracker, uid)) {
638d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // network is blocked; clone and override state
639d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            info = new NetworkInfo(info);
640d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            info.setDetailedState(DetailedState.BLOCKED, null, null);
641c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
642d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        return info;
643c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
644c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
645c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    /**
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return NetworkInfo for the active (i.e., connected) network interface.
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * It is assumed that at most one network is active at a time. If more
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * than one is active, it is indeterminate which will be returned.
64986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * @return the info for the active network, or {@code null} if none is
65086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * active
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
652c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NetworkInfo getActiveNetworkInfo() {
654c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        enforceAccessPermission();
655c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final int uid = Binder.getCallingUid();
656c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return getNetworkInfo(mActiveDefaultNetwork, uid);
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
660c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    public NetworkInfo getActiveNetworkInfoForUid(int uid) {
661c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        enforceConnectivityInternalPermission();
662c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return getNetworkInfo(mActiveDefaultNetwork, uid);
663c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
664c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
665c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NetworkInfo getNetworkInfo(int networkType) {
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceAccessPermission();
668c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final int uid = Binder.getCallingUid();
669c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return getNetworkInfo(networkType, uid);
670c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
671c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
672c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private NetworkInfo getNetworkInfo(int networkType, int uid) {
673c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        NetworkInfo info = null;
674c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        if (isNetworkTypeValid(networkType)) {
675c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[networkType];
676c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            if (tracker != null) {
677fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                info = getFilteredNetworkInfo(tracker, uid);
678c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
680c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return info;
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
683c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NetworkInfo[] getAllNetworkInfo() {
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceAccessPermission();
686c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final int uid = Binder.getCallingUid();
687d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final ArrayList<NetworkInfo> result = Lists.newArrayList();
688fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        synchronized (mRulesLock) {
689c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            for (NetworkStateTracker tracker : mNetTrackers) {
690c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                if (tracker != null) {
691fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                    result.add(getFilteredNetworkInfo(tracker, uid));
692c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                }
693c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
695d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        return result.toArray(new NetworkInfo[result.size()]);
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
698d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    /**
699d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * Return LinkProperties for the active (i.e., connected) default
700d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * network interface.  It is assumed that at most one default network
701d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * is active at a time. If more than one is active, it is indeterminate
702d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * which will be returned.
703d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * @return the ip properties for the active network, or {@code null} if
704d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * none is active
705d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     */
706c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
707d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    public LinkProperties getActiveLinkProperties() {
708599115894f6f960a879d2e3036c547bbf4136020Robert Greenwalt        return getLinkProperties(mActiveDefaultNetwork);
709d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    }
710d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt
711c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
712d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    public LinkProperties getLinkProperties(int networkType) {
713d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt        enforceAccessPermission();
714c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        if (isNetworkTypeValid(networkType)) {
715c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[networkType];
716c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            if (tracker != null) {
717c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                return tracker.getLinkProperties();
718c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
719d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt        }
720d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt        return null;
721d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    }
722d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt
723d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    @Override
724d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    public NetworkState[] getAllNetworkState() {
725d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        enforceAccessPermission();
726d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final int uid = Binder.getCallingUid();
727d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final ArrayList<NetworkState> result = Lists.newArrayList();
728fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        synchronized (mRulesLock) {
729d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            for (NetworkStateTracker tracker : mNetTrackers) {
730d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                if (tracker != null) {
731fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                    final NetworkInfo info = getFilteredNetworkInfo(tracker, uid);
732d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                    result.add(new NetworkState(
733d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                            info, tracker.getLinkProperties(), tracker.getLinkCapabilities()));
734d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                }
735d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            }
736d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        }
737d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        return result.toArray(new NetworkState[result.size()]);
738d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    }
739d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setRadios(boolean turnOn) {
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean result = true;
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (NetworkStateTracker t : mNetTrackers) {
7445154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (t != null) result = t.setRadio(turnOn) && result;
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setRadio(int netType, boolean turnOn) {
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ConnectivityManager.isNetworkTypeValid(netType)) {
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NetworkStateTracker tracker = mNetTrackers[netType];
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return tracker != null && tracker.setRadio(turnOn);
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7589c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    /**
7599c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     * Used to notice when the calling process dies so we can self-expire
7609c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     *
7619c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     * Also used to know if the process has cleaned up after itself when
7629c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     * our auto-expire timer goes off.  The timer has a link to an object.
7639c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     *
7649c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     */
76542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private class FeatureUser implements IBinder.DeathRecipient {
76642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int mNetworkType;
76742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String mFeature;
76842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        IBinder mBinder;
76942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int mPid;
77042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int mUid;
771b928535902b204ac3ec25f161352786842248767Robert Greenwalt        long mCreateTime;
77242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
77342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        FeatureUser(int type, String feature, IBinder binder) {
77442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            super();
77542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mNetworkType = type;
77642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mFeature = feature;
77742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mBinder = binder;
77842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mPid = getCallingPid();
77942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mUid = getCallingUid();
780b928535902b204ac3ec25f161352786842248767Robert Greenwalt            mCreateTime = System.currentTimeMillis();
7819c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
78242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            try {
78342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                mBinder.linkToDeath(this, 0);
78442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } catch (RemoteException e) {
78542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                binderDied();
78642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
78742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
78842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
78942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        void unlinkDeathRecipient() {
79042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mBinder.unlinkToDeath(this, 0);
79142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
79242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
79342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public void binderDied() {
794ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("ConnectivityService FeatureUser binderDied(" +
795b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    mNetworkType + ", " + mFeature + ", " + mBinder + "), created " +
796b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    (System.currentTimeMillis() - mCreateTime) + " mSec ago");
7979c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            stopUsingNetworkFeature(this, false);
79842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
79942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
8009c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        public void expire() {
801ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("ConnectivityService FeatureUser expire(" +
802b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    mNetworkType + ", " + mFeature + ", " + mBinder +"), created " +
803b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    (System.currentTimeMillis() - mCreateTime) + " mSec ago");
8049c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            stopUsingNetworkFeature(this, false);
8059c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
806b928535902b204ac3ec25f161352786842248767Robert Greenwalt
8073bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        public boolean isSameUser(FeatureUser u) {
8083bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            if (u == null) return false;
8093bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
8103bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            return isSameUser(u.mPid, u.mUid, u.mNetworkType, u.mFeature);
8113bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        }
8123bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
8133bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        public boolean isSameUser(int pid, int uid, int networkType, String feature) {
8143bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            if ((mPid == pid) && (mUid == uid) && (mNetworkType == networkType) &&
8153bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                TextUtils.equals(mFeature, feature)) {
8163bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                return true;
8173bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            }
8183bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            return false;
8193bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        }
8203bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
821b928535902b204ac3ec25f161352786842248767Robert Greenwalt        public String toString() {
822b928535902b204ac3ec25f161352786842248767Robert Greenwalt            return "FeatureUser("+mNetworkType+","+mFeature+","+mPid+","+mUid+"), created " +
823b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    (System.currentTimeMillis() - mCreateTime) + " mSec ago";
824b928535902b204ac3ec25f161352786842248767Robert Greenwalt        }
82542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
82642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
8279c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    // javadoc from interface
82842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    public int startUsingNetworkFeature(int networkType, String feature,
82942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            IBinder binder) {
83042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (DBG) {
831ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("startUsingNetworkFeature for net " + networkType + ": " + feature);
83242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
8345154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
835d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                mNetConfigs[networkType] == null) {
83642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            return Phone.APN_REQUEST_FAILED;
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
83842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
8399c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        FeatureUser f = new FeatureUser(networkType, feature, binder);
84042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
84142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // TODO - move this into the MobileDataStateTracker
84242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int usedNetworkType = networkType;
84342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if(networkType == ConnectivityManager.TYPE_MOBILE) {
8442b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville            usedNetworkType = convertFeatureToNetworkType(feature);
8452b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville            if (usedNetworkType < 0) {
8462b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville                Slog.e(TAG, "Can't match any netTracker!");
8472b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville                usedNetworkType = networkType;
84842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
84942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
85050393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
85150393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        if (mProtectedNetworks.contains(usedNetworkType)) {
85250393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            enforceConnectivityInternalPermission();
85350393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        }
85450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
85542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        NetworkStateTracker network = mNetTrackers[usedNetworkType];
85642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (network != null) {
8570be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt            Integer currentPid = new Integer(getCallingPid());
85842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (usedNetworkType != networkType) {
85942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                NetworkStateTracker radio = mNetTrackers[networkType];
86042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                NetworkInfo ni = network.getNetworkInfo();
86142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
86242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                if (ni.isAvailable() == false) {
863ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) log("special network not available");
864e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                    if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
865e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                        return Phone.APN_TYPE_NOT_AVAILABLE;
866e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                    } else {
867e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                        // else make the attempt anyway - probably giving REQUEST_STARTED below
868e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                    }
86942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
87042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
8713bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                int restoreTimer = getRestoreDefaultNetworkDelay(usedNetworkType);
8723bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
8739c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                synchronized(this) {
8743bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    boolean addToList = true;
8753bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    if (restoreTimer < 0) {
8763bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                        // In case there is no timer is specified for the feature,
8773bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                        // make sure we don't add duplicate entry with the same request.
8783bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                        for (FeatureUser u : mFeatureUsers) {
8793bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                            if (u.isSameUser(f)) {
8803bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                                // Duplicate user is found. Do not add.
8813bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                                addToList = false;
8823bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                                break;
8833bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                            }
8843bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                        }
8853bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    }
8863bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
8873bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    if (addToList) mFeatureUsers.add(f);
8889c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
8899c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                        // this gets used for per-pid dns when connected
8909c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                        mNetRequestersPids[usedNetworkType].add(currentPid);
8919c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    }
89242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
8939c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
894f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                if (restoreTimer >= 0) {
895f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                    mHandler.sendMessageDelayed(
896f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                            mHandler.obtainMessage(EVENT_RESTORE_DEFAULT_NETWORK, f), restoreTimer);
897f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                }
89842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
899a64bf834ffa677405af1c87c9f53eed0cd3853ceRobert Greenwalt                if ((ni.isConnectedOrConnecting() == true) &&
900a64bf834ffa677405af1c87c9f53eed0cd3853ceRobert Greenwalt                        !network.isTeardownRequested()) {
90142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    if (ni.isConnected() == true) {
90242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        // add the pid-specific dns
903c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                        handleDnsConfigurationChange(networkType);
904ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        if (DBG) log("special network already active");
90542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return Phone.APN_ALREADY_ACTIVE;
90642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
907ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) log("special network already connecting");
90842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    return Phone.APN_REQUEST_STARTED;
90942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
91042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
91142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // check if the radio in play can make another contact
91242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // assume if cannot for now
91342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
914ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                if (DBG) log("reconnecting to special network");
91542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                network.reconnect();
91642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                return Phone.APN_REQUEST_STARTED;
91742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } else {
9180be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                // need to remember this unsupported request so we respond appropriately on stop
9190be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                synchronized(this) {
9200be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                    mFeatureUsers.add(f);
9210be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                    if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
9220be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                        // this gets used for per-pid dns when connected
9230be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                        mNetRequestersPids[usedNetworkType].add(currentPid);
9240be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                    }
9250be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                }
92602648a4b8422733ed401f07edf8e426318bb2f8dRobert Greenwalt                return -1;
92742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
92942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        return Phone.APN_TYPE_NOT_AVAILABLE;
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9329c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    // javadoc from interface
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int stopUsingNetworkFeature(int networkType, String feature) {
934b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt        enforceChangePermission();
935b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt
9369c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int pid = getCallingPid();
9379c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int uid = getCallingUid();
9389c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
9399c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        FeatureUser u = null;
9409c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        boolean found = false;
9419c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
9429c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        synchronized(this) {
9433bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            for (FeatureUser x : mFeatureUsers) {
9443bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                if (x.isSameUser(pid, uid, networkType, feature)) {
9453bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    u = x;
9469c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    found = true;
9479c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    break;
9489c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                }
9499c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            }
9509c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
9519c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        if (found && u != null) {
9529c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // stop regardless of how many other time this proc had called start
9539c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            return stopUsingNetworkFeature(u, true);
9549c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        } else {
9559c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // none found!
956ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("ignoring stopUsingNetworkFeature - not a live request");
9579c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            return 1;
9589c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
95942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
96042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
9619c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    private int stopUsingNetworkFeature(FeatureUser u, boolean ignoreDups) {
9629c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int networkType = u.mNetworkType;
9639c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        String feature = u.mFeature;
9649c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int pid = u.mPid;
9659c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int uid = u.mUid;
9669c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
9679c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        NetworkStateTracker tracker = null;
9689c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        boolean callTeardown = false;  // used to carry our decision outside of sync block
9699c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
97042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (DBG) {
971ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("stopUsingNetworkFeature for net " + networkType +
97242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    ": " + feature);
97342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
974b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
97842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
9799c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        // need to link the mFeatureUsers list with the mNetRequestersPids state in this
9809c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        // sync block
9819c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        synchronized(this) {
9829c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // check if this process still has an outstanding start request
9839c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            if (!mFeatureUsers.contains(u)) {
984ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                if (DBG) log("ignoring - this process has no outstanding requests");
9859c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                return 1;
9869c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            }
9879c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            u.unlinkDeathRecipient();
9889c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            mFeatureUsers.remove(mFeatureUsers.indexOf(u));
9899c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // If we care about duplicate requests, check for that here.
9909c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            //
9919c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // This is done to support the extension of a request - the app
9929c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // can request we start the network feature again and renew the
9939c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // auto-shutoff delay.  Normal "stop" calls from the app though
9949c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // do not pay attention to duplicate requests - in effect the
9959c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // API does not refcount and a single stop will counter multiple starts.
9969c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            if (ignoreDups == false) {
9973bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                for (FeatureUser x : mFeatureUsers) {
9983bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    if (x.isSameUser(u)) {
999ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        if (DBG) log("ignoring stopUsingNetworkFeature as dup is found");
10009c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                        return 1;
10019c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    }
100242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
100342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
100442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
10059c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // TODO - move to MobileDataStateTracker
10069c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            int usedNetworkType = networkType;
10079c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            if (networkType == ConnectivityManager.TYPE_MOBILE) {
10082b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville                usedNetworkType = convertFeatureToNetworkType(feature);
10092b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville                if (usedNetworkType < 0) {
10102b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville                    usedNetworkType = networkType;
10119c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                }
101242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
10139c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            tracker =  mNetTrackers[usedNetworkType];
10145154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (tracker == null) {
1015ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                if (DBG) log("ignoring - no known tracker for net type " + usedNetworkType);
10165154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                return -1;
10175154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
10185154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (usedNetworkType != networkType) {
10199c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                Integer currentPid = new Integer(pid);
10209c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                mNetRequestersPids[usedNetworkType].remove(currentPid);
1021421c72b6773582dd1473ace44c42d4e0ee1287e3Robert Greenwalt                reassessPidDns(pid, true);
10229c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                if (mNetRequestersPids[usedNetworkType].size() != 0) {
1023ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) log("not tearing down special network - " +
10249c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                           "others still using it");
10259c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    return 1;
10269c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                }
10279c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                callTeardown = true;
102819b9ab46a9faee6031aaf6c78748401943fea117Robert Greenwalt            } else {
102919b9ab46a9faee6031aaf6c78748401943fea117Robert Greenwalt                if (DBG) log("not a known feature - dropping");
103042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
10319c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
1032ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("Doing network teardown");
10339c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        if (callTeardown) {
103442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            tracker.teardown();
103542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            return 1;
103642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        } else {
103702648a4b8422733ed401f07edf8e426318bb2f8dRobert Greenwalt            return -1;
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1042585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @deprecated use requestRouteToHostAddress instead
1043585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     *
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ensure that a network route exists to deliver traffic to the specified
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * host via the specified network interface.
104686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * @param networkType the type of the network over which traffic to the
104786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * specified host is to be routed
104886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * @param hostAddress the IP address of the host to which the route is
104986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * desired
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} on success, {@code false} on failure
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean requestRouteToHost(int networkType, int hostAddress) {
1053585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
1054585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
1055585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        if (inetAddress == null) {
1056585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            return false;
1057585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        }
1058585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
1059585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        return requestRouteToHostAddress(networkType, inetAddress.getAddress());
1060585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    }
1061585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
1062585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    /**
1063585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * Ensure that a network route exists to deliver traffic to the specified
1064585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * host via the specified network interface.
1065585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param networkType the type of the network over which traffic to the
1066585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * specified host is to be routed
1067585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param hostAddress the IP address of the host to which the route is
1068585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * desired
1069585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @return {@code true} on success, {@code false} on failure
1070585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     */
1071585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
107350393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        if (mProtectedNetworks.contains(networkType)) {
107450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            enforceConnectivityInternalPermission();
107550393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        }
107650393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NetworkStateTracker tracker = mNetTrackers[networkType];
10818206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt
10825154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        if (tracker == null || !tracker.getNetworkInfo().isConnected() ||
10835154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                tracker.isTeardownRequested()) {
10848206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt            if (DBG) {
1085ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                log("requestRouteToHostAddress on down network " +
1086585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                           "(" + networkType + ") - dropped");
10878206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt            }
10888206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt            return false;
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
109047f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        try {
1091585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            InetAddress addr = InetAddress.getByAddress(hostAddress);
10920a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            LinkProperties lp = tracker.getLinkProperties();
1093ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            return addRouteToAddress(lp, addr);
109447f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        } catch (UnknownHostException e) {}
109547f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        return false;
1096d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
1097d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
10980a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private boolean addRoute(LinkProperties p, RouteInfo r) {
10990a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return modifyRoute(p.getInterfaceName(), p, r, 0, true);
11000a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
1101d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
11020a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private boolean removeRoute(LinkProperties p, RouteInfo r) {
11030a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return modifyRoute(p.getInterfaceName(), p, r, 0, false);
11040a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
11050a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
1106ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
1107ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        return modifyRouteToAddress(lp, addr, true);
1108ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    }
1109ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt
1110ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
1111ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        return modifyRouteToAddress(lp, addr, false);
1112ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    }
1113ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt
1114ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) {
1115ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr);
1116ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        if (bestRoute == null) {
1117ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            bestRoute = RouteInfo.makeHostRoute(addr);
1118ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        } else {
1119ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (bestRoute.getGateway().equals(addr)) {
1120ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // if there is no better route, add the implied hostroute for our gateway
1121ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                bestRoute = RouteInfo.makeHostRoute(addr);
1122ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            } else {
1123ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // if we will connect to this through another route, add a direct route
1124ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // to it's gateway
1125ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway());
1126ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            }
1127ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        }
1128ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd);
1129ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    }
1130ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt
11310a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
11320a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            boolean doAdd) {
11330a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if ((ifaceName == null) || (lp == null) || (r == null)) return false;
11340a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
11350a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
11360a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            loge("Error adding route - too much recursion");
1137d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            return false;
1138d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1139f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
11400a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (r.isHostRoute() == false) {
11410a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), r.getGateway());
11420a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (bestRoute != null) {
1143476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                if (bestRoute.getGateway().equals(r.getGateway())) {
1144476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    // if there is no better route, add the implied hostroute for our gateway
11450a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    bestRoute = RouteInfo.makeHostRoute(r.getGateway());
1146476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                } else {
1147476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    // if we will connect to our gateway through another route, add a direct
1148476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    // route to it's gateway
1149476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
11500a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
1151476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd);
11520a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
1153f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
11540a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (doAdd) {
11550a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (DBG) log("Adding " + r + " for interface " + ifaceName);
11560a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            mAddedRoutes.add(r);
11570a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            try {
11580a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                mNetd.addRoute(ifaceName, r);
11590a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            } catch (Exception e) {
11600a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                // never crash - catch them all
11610a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                loge("Exception trying to add a route: " + e);
1162f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                return false;
1163f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            }
11640a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        } else {
11650a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // if we remove this one and there are no more like it, then refcount==0 and
11660a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // we can remove it from the table
11670a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            mAddedRoutes.remove(r);
11680a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (mAddedRoutes.contains(r) == false) {
11690a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (DBG) log("Removing " + r + " for interface " + ifaceName);
11700a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                try {
11710a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    mNetd.removeRoute(ifaceName, r);
11720a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                } catch (Exception e) {
11730a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    // never crash - catch them all
11740a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    loge("Exception trying to remove a route: " + e);
11750a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    return false;
11760a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
11770a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            } else {
11780a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (DBG) log("not removing " + r + " as it's still in use");
11790a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
1180f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
11810a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return true;
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see ConnectivityManager#getBackgroundDataSetting()
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getBackgroundDataSetting() {
1188d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt        return mBackgroundDataEnabled.get();
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
119086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see ConnectivityManager#setBackgroundDataSetting(boolean)
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBackgroundDataSetting(boolean allowBackgroundDataUsage) {
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.enforceCallingOrSelfPermission(
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                android.Manifest.permission.CHANGE_BACKGROUND_DATA_SETTING,
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "ConnectivityService");
119886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
1199d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt        mBackgroundDataEnabled.set(allowBackgroundDataUsage);
1200d825ea4ff055eb9302dcb5c8e59fe65bf31f0a41Robert Greenwalt
12018dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_BACKGROUND_DATA,
12028dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                (allowBackgroundDataUsage ? ENABLED : DISABLED), 0));
12038dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
120486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
12058dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleSetBackgroundData(boolean enabled) {
1206db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt        Settings.Secure.putInt(mContext.getContentResolver(),
1207db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt                Settings.Secure.BACKGROUND_DATA, enabled ? 1 : 0);
1208db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt        Intent broadcast = new Intent(
1209db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt                ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
1210db4afae70aa404f20c271965a8d7c1e2d64cb818Robert Greenwalt        mContext.sendBroadcast(broadcast);
121186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt    }
121286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
1213c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    /**
1214c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     * @see ConnectivityManager#getMobileDataEnabled()
1215c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     */
1216c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    public boolean getMobileDataEnabled() {
1217e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        // TODO: This detail should probably be in DataConnectionTracker's
1218e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        //       which is where we store the value and maybe make this
1219e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        //       asynchronous.
1220c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        enforceAccessPermission();
1221c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        boolean retVal = Settings.Secure.getInt(mContext.getContentResolver(),
1222c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt                Settings.Secure.MOBILE_DATA, 1) == 1;
1223ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("getMobileDataEnabled returning " + retVal);
1224c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        return retVal;
1225c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    }
1226c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt
1227d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    public void setDataDependency(int networkType, boolean met) {
122850393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        enforceConnectivityInternalPermission();
122950393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
1230d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_DEPENDENCY_MET,
1231d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                (met ? ENABLED : DISABLED), networkType));
1232d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    }
1233d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt
1234d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    private void handleSetDependencyMet(int networkType, boolean met) {
1235d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetTrackers[networkType] != null) {
1236d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (DBG) {
1237d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                log("handleSetDependencyMet(" + networkType + ", " + met + ")");
1238d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            }
1239d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            mNetTrackers[networkType].setDependencyMet(met);
1240d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        }
1241d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    }
1242d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt
1243c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
1244c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        @Override
1245fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        public void onUidRulesChanged(int uid, int uidRules) {
1246c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // only someone like NPMS should only be calling us
12471a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey            mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1248c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1249c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            if (LOGD_RULES) {
1250fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                Slog.d(TAG, "onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
1251c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
1252c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1253fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            synchronized (mRulesLock) {
1254c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                // skip update when we've already applied rules
1255c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                final int oldRules = mUidRules.get(uid, RULE_ALLOW_ALL);
1256c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                if (oldRules == uidRules) return;
1257c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1258c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                mUidRules.put(uid, uidRules);
1259c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
1260c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1261c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // TODO: dispatch into NMS to push rules towards kernel module
1262c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // TODO: notify UID when it has requested targeted updates
1263c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
1264fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
1265fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        @Override
1266fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        public void onMeteredIfacesChanged(String[] meteredIfaces) {
1267fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            // only someone like NPMS should only be calling us
1268fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1269fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
1270fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            if (LOGD_RULES) {
1271fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                Slog.d(TAG,
1272fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                        "onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
1273fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            }
1274fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
1275fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            synchronized (mRulesLock) {
1276fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                mMeteredIfaces.clear();
1277fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                for (String iface : meteredIfaces) {
1278fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                    mMeteredIfaces.add(iface);
1279fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                }
1280fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            }
1281fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        }
1282c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    };
1283c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1284c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    /**
1285c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     * @see ConnectivityManager#setMobileDataEnabled(boolean)
1286c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     */
12878dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    public void setMobileDataEnabled(boolean enabled) {
1288c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        enforceChangePermission();
1289ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("setMobileDataEnabled(" + enabled + ")");
1290c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt
12918dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA,
1292d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                (enabled ? ENABLED : DISABLED), 0));
12938dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
12948dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
12958dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleSetMobileData(boolean enabled) {
1296e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {
1297e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville            if (DBG) {
1298e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville                Slog.d(TAG, mNetTrackers[ConnectivityManager.TYPE_MOBILE].toString() + enabled);
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1300e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville            mNetTrackers[ConnectivityManager.TYPE_MOBILE].setDataEnable(enabled);
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enforceAccessPermission() {
130586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt        mContext.enforceCallingOrSelfPermission(
130686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                android.Manifest.permission.ACCESS_NETWORK_STATE,
130786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                "ConnectivityService");
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enforceChangePermission() {
131186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt        mContext.enforceCallingOrSelfPermission(
131286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                android.Manifest.permission.CHANGE_NETWORK_STATE,
131386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                "ConnectivityService");
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1316d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // TODO Make this a special check when it goes public
1317d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    private void enforceTetherChangePermission() {
1318d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        mContext.enforceCallingOrSelfPermission(
1319d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt                android.Manifest.permission.CHANGE_NETWORK_STATE,
1320d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt                "ConnectivityService");
1321d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
1322d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
13232a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    private void enforceTetherAccessPermission() {
13242a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        mContext.enforceCallingOrSelfPermission(
13252a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt                android.Manifest.permission.ACCESS_NETWORK_STATE,
13262a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt                "ConnectivityService");
13272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
13282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
132914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private void enforceConnectivityInternalPermission() {
133014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mContext.enforceCallingOrSelfPermission(
133114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                android.Manifest.permission.CONNECTIVITY_INTERNAL,
133214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                "ConnectivityService");
133314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    }
133414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
133686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * Handle a {@code DISCONNECTED} event. If this pertains to the non-active
133786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * network, we ignore it. If it is for the active network, we send out a
133886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * broadcast. But first, we check whether it might be possible to connect
133986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * to a different network.
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info the {@code NetworkInfo} for the network
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleDisconnect(NetworkInfo info) {
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
134442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int prevNetType = info.getType();
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
134642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        mNetTrackers[prevNetType].setTeardownRequested(false);
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If the disconnected network is not the active one, then don't report
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * this as a loss of connectivity. What probably happened is that we're
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * getting the disconnect for a network that we explicitly disabled
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * in accordance with network preference policies.
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1353d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (!mNetConfigs[prevNetType].isDefault()) {
135442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            List pids = mNetRequestersPids[prevNetType];
135542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            for (int i = 0; i<pids.size(); i++) {
135642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                Integer pid = (Integer)pids.get(i);
135742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // will remove them because the net's no longer connected
135842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // need to do this now as only now do we know the pids and
135942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // can properly null things that are no longer referenced.
136042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                reassessPidDns(pid.intValue(), false);
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.isFailover()) {
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            info.setFailover(false);
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getReason() != null) {
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getExtraInfo() != null) {
137486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
137586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    info.getExtraInfo());
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
137742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1378d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[prevNetType].isDefault()) {
1379f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            tryFailover(prevNetType);
1380f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            if (mActiveDefaultNetwork != -1) {
1381f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
1382cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
1383cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            } else {
1384029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt                mDefaultInetConditionPublished = 0; // we're not connected anymore
1385cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
1386cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            }
1387da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
1388029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
1389ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt
1390ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        // Reset interface if no other connections are using the same interface
1391ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        boolean doReset = true;
1392ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        LinkProperties linkProperties = mNetTrackers[prevNetType].getLinkProperties();
1393ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        if (linkProperties != null) {
1394ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            String oldIface = linkProperties.getInterfaceName();
1395ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            if (TextUtils.isEmpty(oldIface) == false) {
1396ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                for (NetworkStateTracker networkStateTracker : mNetTrackers) {
1397ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    if (networkStateTracker == null) continue;
1398ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    NetworkInfo networkInfo = networkStateTracker.getNetworkInfo();
1399ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    if (networkInfo.isConnected() && networkInfo.getType() != prevNetType) {
1400ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        LinkProperties l = networkStateTracker.getLinkProperties();
1401ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        if (l == null) continue;
1402ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        if (oldIface.equals(l.getInterfaceName())) {
1403ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                            doReset = false;
1404ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                            break;
1405ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        }
1406ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    }
1407ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                }
1408ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            }
1409ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        }
1410ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt
1411da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        // do this before we broadcast the change
1412ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        handleConnectivityChange(prevNetType, doReset);
1413da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt
1414da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        sendStickyBroadcast(intent);
1415da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        /*
1416da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * If the failover network is already connected, then immediately send
1417da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * out a followup broadcast indicating successful failover
1418da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         */
1419f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt        if (mActiveDefaultNetwork != -1) {
1420f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            sendConnectedBroadcast(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo());
1421da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
1422da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt    }
1423da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt
1424f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt    private void tryFailover(int prevNetType) {
142542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        /*
1426bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt         * If this is a default network, check if other defaults are available.
1427bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt         * Try to reconnect on all available and let them hash it out when
1428bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt         * more than one connects.
142942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         */
1430d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[prevNetType].isDefault()) {
143142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (mActiveDefaultNetwork == prevNetType) {
143242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                mActiveDefaultNetwork = -1;
143342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
143442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1435f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            // don't signal a reconnect for anything lower or equal priority than our
1436f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            // current connected default
1437f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            // TODO - don't filter by priority now - nice optimization but risky
1438f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt//            int currentPriority = -1;
1439f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt//            if (mActiveDefaultNetwork != -1) {
1440d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt//                currentPriority = mNetConfigs[mActiveDefaultNetwork].mPriority;
1441f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt//            }
1442da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt            for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
14435154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                if (checkType == prevNetType) continue;
1444d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                if (mNetConfigs[checkType] == null) continue;
1445d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                if (!mNetConfigs[checkType].isDefault()) continue;
14469f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville
14479f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// Enabling the isAvailable() optimization caused mobile to not get
14489f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// selected if it was in the middle of error handling. Specifically
14499f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// a moble connection that took 30 seconds to complete the DEACTIVATE_DATA_CALL
14509f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// would not be available and we wouldn't get connected to anything.
14519f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// So removing the isAvailable() optimization below for now. TODO: This
14529f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// optimization should work and we need to investigate why it doesn't work.
14539f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// This could be related to how DEACTIVATE_DATA_CALL is reporting its
14549f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// complete before it is really complete.
14559f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville//                if (!mNetTrackers[checkType].isAvailable()) continue;
14569f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville
1457d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt//                if (currentPriority >= mNetConfigs[checkType].mPriority) continue;
1458bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt
1459f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkStateTracker checkTracker = mNetTrackers[checkType];
1460f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkInfo checkInfo = checkTracker.getNetworkInfo();
1461f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                if (!checkInfo.isConnectedOrConnecting() || checkTracker.isTeardownRequested()) {
1462f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                    checkInfo.setFailover(true);
1463f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                    checkTracker.reconnect();
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1465f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                if (DBG) log("Attempting to switch to " + checkInfo.getTypeName());
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void sendConnectedBroadcast(NetworkInfo info) {
14711e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt        sendGeneralBroadcast(info, ConnectivityManager.CONNECTIVITY_ACTION);
14721e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    }
14731e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt
14741e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    private void sendInetConditionBroadcast(NetworkInfo info) {
14751e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt        sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
14761e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    }
14771e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt
14781e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
14791e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt        Intent intent = new Intent(bcastType);
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.isFailover()) {
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            info.setFailover(false);
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getReason() != null) {
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getExtraInfo() != null) {
148986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
149086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    info.getExtraInfo());
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1492d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
14930f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        sendStickyBroadcast(intent);
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when an attempt to fail over to another network has failed.
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info the {@link NetworkInfo} for the failed network
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleConnectionFailure(NetworkInfo info) {
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNetTrackers[info.getType()].setTeardownRequested(false);
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
150342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String reason = info.getReason();
150442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String extraInfo = info.getExtraInfo();
150542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1506572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt        String reasonText;
1507572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt        if (reason == null) {
1508572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt            reasonText = ".";
1509572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt        } else {
1510572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt            reasonText = " (" + reason + ").";
151142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
1512ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        loge("Attempt to connect to " + info.getTypeName() + " failed" + reasonText);
151386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
151442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
151542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
151642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (getActiveNetworkInfo() == null) {
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
151942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (reason != null) {
152042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_REASON, reason);
152142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
152242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (extraInfo != null) {
152342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, extraInfo);
152442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
152542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (info.isFailover()) {
152642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
152742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            info.setFailover(false);
152842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
1529da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt
1530d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[info.getType()].isDefault()) {
1531f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            tryFailover(info.getType());
1532f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            if (mActiveDefaultNetwork != -1) {
1533f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
1534cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
1535cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            } else {
1536029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt                mDefaultInetConditionPublished = 0;
1537cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
1538cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            }
1539da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
1540cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt
1541029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
15420f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        sendStickyBroadcast(intent);
1543da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        /*
1544da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * If the failover network is already connected, then immediately send
1545da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * out a followup broadcast indicating successful failover
1546da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         */
1547f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt        if (mActiveDefaultNetwork != -1) {
1548f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            sendConnectedBroadcast(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo());
1549da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
15500f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    }
15510f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood
15520f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    private void sendStickyBroadcast(Intent intent) {
15530f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        synchronized(this) {
15541c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            if (!mSystemReady) {
15551c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn                mInitialBroadcast = new Intent(intent);
15560f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood            }
15571c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
15581c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            mContext.sendStickyBroadcast(intent);
15590f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        }
15600f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    }
15610f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood
15620f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    void systemReady() {
15630f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        synchronized(this) {
15640f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood            mSystemReady = true;
15651c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            if (mInitialBroadcast != null) {
15661c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn                mContext.sendStickyBroadcast(mInitialBroadcast);
15671c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn                mInitialBroadcast = null;
15680f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood            }
15690f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        }
1570434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        // load the global proxy at startup
1571434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY));
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleConnect(NetworkInfo info) {
157542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int type = info.getType();
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // snapshot isFailover, because sendConnectedBroadcast() resets it
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isFailover = info.isFailover();
157942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        NetworkStateTracker thisNet = mNetTrackers[type];
158042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
158142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // if this is a default net and other default is running
158242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // kill the one not preferred
1583d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[type].isDefault()) {
158442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
158542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                if ((type != mNetworkPreference &&
1586975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[mActiveDefaultNetwork].priority >
1587975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        mNetConfigs[type].priority) ||
158842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        mNetworkPreference == mActiveDefaultNetwork) {
158942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        // don't accept this one
1590ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        if (DBG) {
1591ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                            log("Not broadcasting CONNECT_ACTION " +
159242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                                "to torn down network " + info.getTypeName());
1593ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        }
159442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        teardown(thisNet);
159542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return;
159642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                } else {
159742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    // tear down the other
159842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    NetworkStateTracker otherNet =
159942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                            mNetTrackers[mActiveDefaultNetwork];
1600ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) {
1601ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        log("Policy requires " + otherNet.getNetworkInfo().getTypeName() +
160242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                            " teardown");
1603ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    }
160442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    if (!teardown(otherNet)) {
1605ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        loge("Network declined teardown request");
160627725e8cd1e2eb3b88186ae8d43e437f130b1f84Robert Greenwalt                        teardown(thisNet);
160742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return;
160842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
160914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                }
161014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            }
161114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            synchronized (ConnectivityService.this) {
161214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                // have a new default network, release the transition wakelock in a second
161314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                // if it's held.  The second pause is to allow apps to reconnect over the
161414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                // new network
161514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                if (mNetTransitionWakeLock.isHeld()) {
161614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    mHandler.sendMessageDelayed(mHandler.obtainMessage(
1617f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt                            EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
161814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            mNetTransitionWakeLockSerialNumber, 0),
161914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            1000);
162042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
162242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mActiveDefaultNetwork = type;
1623d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // this will cause us to come up initially as unconnected and switching
1624d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // to connected after our normal pause unless somebody reports us as reall
1625d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // disconnected
1626d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            mDefaultInetConditionPublished = 0;
1627d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            mDefaultConnectionSequence++;
1628d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            mInetConditionChangeInFlight = false;
1629d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // Don't do this - if we never sign in stay, grey
1630d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            //reportNetworkCondition(mActiveDefaultNetwork, 100);
16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
163242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        thisNet.setTeardownRequested(false);
1633d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        updateNetworkSettings(thisNet);
1634ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        handleConnectivityChange(type, false);
163542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        sendConnectedBroadcast(info);
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1639c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * After a change in the connectivity state of a network. We're mainly
1640c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * concerned with making sure that the list of DNS servers is set up
1641c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * according to which networks are connected, and ensuring that the
1642c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * right routing table entries exist.
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1644ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt    private void handleConnectivityChange(int netType, boolean doReset) {
1645e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0;
1646e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
164842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         * If a non-default network is enabled, add the host routes that
1649c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt         * will allow it's DNS servers to be accessed.
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1651c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        handleDnsConfigurationChange(netType);
165242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
16530a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        LinkProperties curLp = mCurrentLinkProperties[netType];
16540a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        LinkProperties newLp = null;
16550a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
1656c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
16570a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            newLp = mNetTrackers[netType].getLinkProperties();
1658e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            if (VDBG) {
1659e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
1660e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        " doReset=" + doReset + " resetMask=" + resetMask +
1661e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        "\n   curLp=" + curLp +
1662e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        "\n   newLp=" + newLp);
1663e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            }
1664e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
16650a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (curLp != null) {
16660a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (curLp.isIdenticalInterfaceName(newLp)) {
16670a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    CompareResult<LinkAddress> car = curLp.compareAddresses(newLp);
16680a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    if ((car.removed.size() != 0) || (car.added.size() != 0)) {
16690a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        for (LinkAddress linkAddr : car.removed) {
16700a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            if (linkAddr.getAddress() instanceof Inet4Address) {
16710a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                resetMask |= NetworkUtils.RESET_IPV4_ADDRESSES;
16720a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            }
16730a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            if (linkAddr.getAddress() instanceof Inet6Address) {
16740a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                resetMask |= NetworkUtils.RESET_IPV6_ADDRESSES;
16750a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            }
1676e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        }
16770a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        if (DBG) {
16780a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            log("handleConnectivityChange: addresses changed" +
16790a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                    " linkProperty[" + netType + "]:" + " resetMask=" + resetMask +
16800a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                    "\n   car=" + car);
16810a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        }
16820a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    } else {
16830a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        if (DBG) {
16840a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            log("handleConnectivityChange: address are the same reset per doReset" +
16850a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                   " linkProperty[" + netType + "]:" +
16860a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                   " resetMask=" + resetMask);
1687e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        }
1688e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    }
1689e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                } else {
16900a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    resetMask = NetworkUtils.RESET_ALL_ADDRESSES;
16910a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    log("handleConnectivityChange: interface not not equivalent reset both" +
16920a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            " linkProperty[" + netType + "]:" +
16930a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            " resetMask=" + resetMask);
1694e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                }
1695e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            }
1696d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (mNetConfigs[netType].isDefault()) {
1697434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                handleApplyDefaultProxy(netType);
1698c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            }
1699c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        } else {
17000a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (VDBG) {
17010a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
17020a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        " doReset=" + doReset + " resetMask=" + resetMask +
17030a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        "\n  curLp=" + curLp +
17040a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        "\n  newLp= null");
170542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17070a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        mCurrentLinkProperties[netType] = newLp;
17080a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        updateRoutes(newLp, curLp, mNetConfigs[netType].isDefault());
1709ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt
1710e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        if (doReset || resetMask != 0) {
1711ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
1712ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            if (linkProperties != null) {
1713ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                String iface = linkProperties.getInterfaceName();
1714ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                if (TextUtils.isEmpty(iface) == false) {
1715e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    if (DBG) log("resetConnections(" + iface + ", " + resetMask + ")");
1716e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    NetworkUtils.resetConnections(iface, resetMask);
1717ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                }
1718ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            }
1719ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        }
17201ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo
17211ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        // TODO: Temporary notifying upstread change to Tethering.
17221ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        //       @see bug/4455071
17231ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        /** Notify TetheringService if interface name has been changed. */
17241ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
17251ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                             Phone.REASON_LINK_PROPERTIES_CHANGED)) {
17261ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo            if (isTetheringSupported()) {
17271ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                mTethering.handleTetherIfaceChange();
17281ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo            }
17291ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        }
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17320a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    /**
17330a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * Add and remove routes using the old properties (null if not previously connected),
17340a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * new properties (null if becoming disconnected).  May even be double null, which
17350a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * is a noop.
17360a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * Uses isLinkDefault to determine if default routes should be set or conversely if
17370a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * host routes should be set to the dns servers
17380a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     */
17390a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private void updateRoutes(LinkProperties newLp, LinkProperties curLp, boolean isLinkDefault) {
17400a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        Collection<RouteInfo> routesToAdd = null;
1741ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        CompareResult<InetAddress> dnsDiff = new CompareResult<InetAddress>();
1742ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
17430a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (curLp != null) {
17440a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // check for the delta between the current set and the new
1745ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            routeDiff = curLp.compareRoutes(newLp);
17460a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            dnsDiff = curLp.compareDnses(newLp);
1747ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        } else if (newLp != null) {
1748ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            routeDiff.added = newLp.getRoutes();
1749ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            dnsDiff.added = newLp.getDnses();
1750d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1751d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1752ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        for (RouteInfo r : routeDiff.removed) {
1753ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (isLinkDefault || ! r.isDefaultRoute()) {
1754ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                removeRoute(curLp, r);
1755d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
1756ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        }
175759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
1758ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        for (RouteInfo r :  routeDiff.added) {
1759ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (isLinkDefault || ! r.isDefaultRoute()) {
1760ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                addRoute(newLp, r);
176159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            }
1762d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1763d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
17640a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (!isLinkDefault) {
17650a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // handle DNS routes
1766ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (routeDiff.removed.size() == 0 && routeDiff.added.size() == 0) {
1767ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // no change in routes, check for change in dns themselves
1768ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                for (InetAddress oldDns : dnsDiff.removed) {
1769ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    removeRouteToAddress(curLp, oldDns);
1770edcb4f9d560a85970030e1df70426e8d1e2267d2Robert Greenwalt                }
1771ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                for (InetAddress newDns : dnsDiff.added) {
1772ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    addRouteToAddress(newLp, newDns);
177359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                }
1774ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            } else {
1775ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // routes changed - remove all old dns entries and add new
1776ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                if (curLp != null) {
1777ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    for (InetAddress oldDns : curLp.getDnses()) {
1778ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                        removeRouteToAddress(curLp, oldDns);
1779ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    }
1780ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                }
1781ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                if (newLp != null) {
1782ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    for (InetAddress newDns : newLp.getDnses()) {
1783ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                        addRouteToAddress(newLp, newDns);
1784ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    }
1785edcb4f9d560a85970030e1df70426e8d1e2267d2Robert Greenwalt                }
1786d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
1787d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1788d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
1789d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
17900a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
1791d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff   /**
1792d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * Reads the network specific TCP buffer sizes from SystemProperties
1793d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
1794d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * wide use
1795d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     */
1796d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff   public void updateNetworkSettings(NetworkStateTracker nt) {
1797d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        String key = nt.getTcpBufferSizesPropName();
1798d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        String bufferSizes = SystemProperties.get(key);
1799d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1800d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        if (bufferSizes.length() == 0) {
1801ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            loge(key + " not found in system properties. Using defaults");
1802d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1803d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            // Setting to default values so we won't be stuck to previous values
1804d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            key = "net.tcp.buffersize.default";
1805d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            bufferSizes = SystemProperties.get(key);
1806d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1807d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1808d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        // Set values in kernel
1809d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        if (bufferSizes.length() != 0) {
1810d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            if (DBG) {
1811ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                log("Setting TCP values: [" + bufferSizes
1812d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff                        + "] which comes from [" + key + "]");
1813d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
1814d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            setBufferSize(bufferSizes);
1815d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1816d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
1817d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1818d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff   /**
1819d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
1820d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
1821d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     *
1822d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * @param bufferSizes in the format of "readMin, readInitial, readMax,
1823d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     *        writeMin, writeInitial, writeMax"
1824d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     */
1825d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    private void setBufferSize(String bufferSizes) {
1826d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        try {
1827d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            String[] values = bufferSizes.split(",");
1828d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
1829d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            if (values.length == 6) {
1830d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff              final String prefix = "/sys/kernel/ipv4/tcp_";
1831da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "rmem_min", values[0]);
1832da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "rmem_def", values[1]);
1833da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "rmem_max", values[2]);
1834da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "wmem_min", values[3]);
1835da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "wmem_def", values[4]);
1836da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "wmem_max", values[5]);
1837d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            } else {
1838ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Invalid buffersize string: " + bufferSizes);
1839d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
1840d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        } catch (IOException e) {
1841ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            loge("Can't set tcp buffer sizes:" + e);
1842d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1843d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
1844d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
184542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    /**
184642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * Adjust the per-process dns entries (net.dns<x>.<pid>) based
184742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * on the highest priority active net which this process requested.
184842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * If there aren't any, clear it out
184942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     */
185042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private void reassessPidDns(int myPid, boolean doBump)
185142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    {
1852ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("reassessPidDns for pid " + myPid);
185342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        for(int i : mPriorityList) {
1854d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (mNetConfigs[i].isDefault()) {
185542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                continue;
185642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
185742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            NetworkStateTracker nt = mNetTrackers[i];
185842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (nt.getNetworkInfo().isConnected() &&
185942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    !nt.isTeardownRequested()) {
186037e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                LinkProperties p = nt.getLinkProperties();
186147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                if (p == null) continue;
186242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                List pids = mNetRequestersPids[i];
186342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                for (int j=0; j<pids.size(); j++) {
186442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    Integer pid = (Integer)pids.get(j);
186542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    if (pid.intValue() == myPid) {
186647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                        Collection<InetAddress> dnses = p.getDnses();
186747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                        writePidDns(dnses, myPid);
186842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        if (doBump) {
186942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                            bumpDns();
187042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        }
187142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return;
187242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
187342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
187442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt           }
187542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
187642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // nothing found - delete
187742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        for (int i = 1; ; i++) {
187842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            String prop = "net.dns" + i + "." + myPid;
187942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (SystemProperties.get(prop).length() == 0) {
188042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                if (doBump) {
188142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    bumpDns();
188242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
188342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                return;
188442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
188542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            SystemProperties.set(prop, "");
188642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
188742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
188842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
18891039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt    // return true if results in a change
18901039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt    private boolean writePidDns(Collection <InetAddress> dnses, int pid) {
189142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int j = 1;
18921039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt        boolean changed = false;
189347f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        for (InetAddress dns : dnses) {
18941039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            String dnsString = dns.getHostAddress();
18951039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            if (changed || !dnsString.equals(SystemProperties.get("net.dns" + j + "." + pid))) {
18961039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                changed = true;
18971039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                SystemProperties.set("net.dns" + j++ + "." + pid, dns.getHostAddress());
18981039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            }
189942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
19001039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt        return changed;
190142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
190242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
190342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private void bumpDns() {
19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
190542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         * Bump the property that tells the name resolver library to reread
190642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         * the DNS server list from the properties.
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
190842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String propVal = SystemProperties.get("net.dnschange");
190942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int n = 0;
191042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (propVal.length() != 0) {
191142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            try {
191242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                n = Integer.parseInt(propVal);
191342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } catch (NumberFormatException e) {}
191442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
191542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        SystemProperties.set("net.dnschange", "" + (n+1));
191603595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        /*
191703595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt         * Tell the VMs to toss their DNS caches
191803595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt         */
191903595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        Intent intent = new Intent(Intent.ACTION_CLEAR_DNS_CACHE);
192003595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
19213d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt        /*
19223d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt         * Connectivity events can happen before boot has completed ...
19233d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt         */
19243d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
192503595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        mContext.sendBroadcast(intent);
192642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
192844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    // Caller must grab mDnsLock.
1929a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt    private boolean updateDns(String network, String iface,
1930a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            Collection<InetAddress> dnses, String domains) {
193144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        boolean changed = false;
193244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        int last = 0;
193344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        if (dnses.size() == 0 && mDefaultDns != null) {
193444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            ++last;
193544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            String value = mDefaultDns.getHostAddress();
193644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (!value.equals(SystemProperties.get("net.dns1"))) {
193744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                if (DBG) {
193844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    log("no dns provided for " + network + " - using " + value);
193944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
194044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                changed = true;
194144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                SystemProperties.set("net.dns1", value);
194244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
194344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        } else {
194444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            for (InetAddress dns : dnses) {
194544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                ++last;
194644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                String key = "net.dns" + last;
194744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                String value = dns.getHostAddress();
194844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                if (!changed && value.equals(SystemProperties.get(key))) {
194944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    continue;
195044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
195144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                if (DBG) {
195244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    log("adding dns " + value + " for " + network);
195344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
195444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                changed = true;
195544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                SystemProperties.set(key, value);
195644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
195744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        }
195844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        for (int i = last + 1; i <= mNumDnsEntries; ++i) {
195944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            String key = "net.dns" + i;
196044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (DBG) log("erasing " + key);
196144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            changed = true;
196244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            SystemProperties.set(key, "");
196344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        }
196444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        mNumDnsEntries = last;
196544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
1966a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        if (changed) {
1967a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            try {
1968a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses));
1969a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                mNetd.setDefaultInterfaceForDns(iface);
1970a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            } catch (Exception e) {
1971a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                Slog.e(TAG, "exception setting default dns interface: " + e);
1972a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            }
1973a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        }
197444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        if (!domains.equals(SystemProperties.get("net.dns.search"))) {
197544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            SystemProperties.set("net.dns.search", domains);
197644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            changed = true;
197744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        }
197844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        return changed;
197944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    }
198044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
1981c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt    private void handleDnsConfigurationChange(int netType) {
198242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // add default net's dns entries
1983c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        NetworkStateTracker nt = mNetTrackers[netType];
1984c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
198537e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt            LinkProperties p = nt.getLinkProperties();
1986c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            if (p == null) return;
1987c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            Collection<InetAddress> dnses = p.getDnses();
19881039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            boolean changed = false;
1989d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (mNetConfigs[netType].isDefault()) {
199044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                String network = nt.getNetworkInfo().getTypeName();
199144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                synchronized (mDnsLock) {
199244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    if (!mDnsOverridden) {
1993a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                        changed = updateDns(network, p.getInterfaceName(), dnses, "");
19941039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                    }
1995c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                }
1996c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            } else {
19971efe4d5cfd3913b3c4efa7aee4bf9fea262c0ad2Robert Greenwalt                try {
1998c59c6da9ae14097c77eee69285c6eacc8130936cRobert Greenwalt                    mNetd.setDnsServersForInterface(p.getInterfaceName(),
1999a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                            NetworkUtils.makeStrings(dnses));
20001efe4d5cfd3913b3c4efa7aee4bf9fea262c0ad2Robert Greenwalt                } catch (Exception e) {
2001a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                    Slog.e(TAG, "exception setting dns servers: " + e);
2002c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                }
2003c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                // set per-pid dns for attached secondary nets
2004c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                List pids = mNetRequestersPids[netType];
2005c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                for (int y=0; y< pids.size(); y++) {
2006c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                    Integer pid = (Integer)pids.get(y);
20071039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                    changed = writePidDns(dnses, pid.intValue());
20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
20101039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            if (changed) bumpDns();
20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
201242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
201342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
2014f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt    private int getRestoreDefaultNetworkDelay(int networkType) {
201542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String restoreDefaultNetworkDelayStr = SystemProperties.get(
201642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                NETWORK_RESTORE_DELAY_PROP_NAME);
201742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if(restoreDefaultNetworkDelayStr != null &&
201842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                restoreDefaultNetworkDelayStr.length() != 0) {
201942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            try {
202042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                return Integer.valueOf(restoreDefaultNetworkDelayStr);
202142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } catch (NumberFormatException e) {
202242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2024f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        // if the system property isn't set, use the value for the apn type
2025f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        int ret = RESTORE_DEFAULT_NETWORK_DELAY;
2026f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt
2027f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) &&
2028f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                (mNetConfigs[networkType] != null)) {
2029f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt            ret = mNetConfigs[networkType].restoreTime;
2030f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        }
2031f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        return ret;
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
203686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt        if (mContext.checkCallingOrSelfPermission(
203786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                android.Manifest.permission.DUMP)
20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                != PackageManager.PERMISSION_GRANTED) {
203986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt            pw.println("Permission Denial: can't dump ConnectivityService " +
204086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    "from from pid=" + Binder.getCallingPid() + ", uid=" +
204186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    Binder.getCallingUid());
20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pw.println();
20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (NetworkStateTracker nst : mNetTrackers) {
2046b928535902b204ac3ec25f161352786842248767Robert Greenwalt            if (nst != null) {
2047b928535902b204ac3ec25f161352786842248767Robert Greenwalt                if (nst.getNetworkInfo().isConnected()) {
2048b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    pw.println("Active network: " + nst.getNetworkInfo().
2049b928535902b204ac3ec25f161352786842248767Robert Greenwalt                            getTypeName());
2050b928535902b204ac3ec25f161352786842248767Robert Greenwalt                }
2051b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pw.println(nst.getNetworkInfo());
2052b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pw.println(nst);
2053b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pw.println();
2054b928535902b204ac3ec25f161352786842248767Robert Greenwalt            }
2055b928535902b204ac3ec25f161352786842248767Robert Greenwalt        }
2056b928535902b204ac3ec25f161352786842248767Robert Greenwalt
2057b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println("Network Requester Pids:");
2058b928535902b204ac3ec25f161352786842248767Robert Greenwalt        for (int net : mPriorityList) {
2059b928535902b204ac3ec25f161352786842248767Robert Greenwalt            String pidString = net + ": ";
2060b928535902b204ac3ec25f161352786842248767Robert Greenwalt            for (Object pid : mNetRequestersPids[net]) {
2061b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pidString = pidString + pid.toString() + ", ";
206242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
2063b928535902b204ac3ec25f161352786842248767Robert Greenwalt            pw.println(pidString);
20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2065b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println();
2066b928535902b204ac3ec25f161352786842248767Robert Greenwalt
2067b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println("FeatureUsers:");
2068b928535902b204ac3ec25f161352786842248767Robert Greenwalt        for (Object requester : mFeatureUsers) {
2069b928535902b204ac3ec25f161352786842248767Robert Greenwalt            pw.println(requester.toString());
2070b928535902b204ac3ec25f161352786842248767Robert Greenwalt        }
2071b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println();
20722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
207314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        synchronized (this) {
207414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            pw.println("NetworkTranstionWakeLock is currently " +
207514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
207614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
207714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        }
207814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        pw.println();
207914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
20802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        mTethering.dump(fd, pw, args);
20814e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt
20824e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        if (mInetLog != null) {
20834e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            pw.println();
20844e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            pw.println("Inet condition reports:");
20854e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            for(int i = 0; i < mInetLog.size(); i++) {
20864e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                pw.println(mInetLog.get(i));
20874e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            }
20884e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        }
20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // must be stateless - things change under us.
20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class MyHandler extends Handler {
2093bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        public MyHandler(Looper looper) {
2094bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville            super(looper);
2095bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        }
2096bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville
20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void handleMessage(Message msg) {
20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NetworkInfo info;
21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (msg.what) {
21019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case NetworkStateTracker.EVENT_STATE_CHANGED:
21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    info = (NetworkInfo) msg.obj;
2103511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    int type = info.getType();
2104511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    NetworkInfo.State state = info.getState();
2105511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt
2106ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) log("ConnectivityChange for " +
210786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                            info.getTypeName() + ": " +
2108511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                            state + "/" + info.getDetailedState());
21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Connectivity state changed:
21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // [31-13] Reserved for future use
211286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    // [12-9] Network subtype (for mobile network, as defined
211386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    //         by TelephonyManager)
211486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    // [8-3] Detailed state ordinal (as defined by
211586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    //         NetworkInfo.DetailedState)
21169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // [2-0] Network type (as defined by ConnectivityManager)
21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int eventLogParam = (info.getType() & 0x7) |
21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ((info.getDetailedState().ordinal() & 0x3f) << 3) |
21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (info.getSubtype() << 9);
2120ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker                    EventLog.writeEvent(EventLogTags.CONNECTIVITY_STATE_CHANGED,
212186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                            eventLogParam);
212286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
212386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    if (info.getDetailedState() ==
212486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                            NetworkInfo.DetailedState.FAILED) {
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleConnectionFailure(info);
2126511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    } else if (state == NetworkInfo.State.DISCONNECTED) {
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleDisconnect(info);
2128511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    } else if (state == NetworkInfo.State.SUSPENDED) {
21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // TODO: need to think this over.
213086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // the logic here is, handle SUSPENDED the same as
213186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // DISCONNECTED. The only difference being we are
213286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // broadcasting an intent with NetworkInfo that's
213386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // suspended. This allows the applications an
213486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // opportunity to handle DISCONNECTED and SUSPENDED
213586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // differently, or not.
21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleDisconnect(info);
2137511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    } else if (state == NetworkInfo.State.CONNECTED) {
21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleConnect(info);
21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED:
2142c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                    info = (NetworkInfo) msg.obj;
21431ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    // TODO: Temporary allowing network configuration
21441ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    //       change not resetting sockets.
21451ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    //       @see bug/4455071
21461ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    handleConnectivityChange(info.getType(), false);
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
2148f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt                case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
214914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    String causedBy = null;
215014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    synchronized (ConnectivityService.this) {
215114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                        if (msg.arg1 == mNetTransitionWakeLockSerialNumber &&
215214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                                mNetTransitionWakeLock.isHeld()) {
215314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            mNetTransitionWakeLock.release();
215414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            causedBy = mNetTransitionWakeLockCausedBy;
215514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                        }
215614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    }
215714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    if (causedBy != null) {
2158ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        log("NetTransition Wakelock for " + causedBy + " released by timeout");
215914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    }
2160057d5e9824a01a03c13d5a32d3c7f5023d01586eRobert Greenwalt                    break;
21618dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_RESTORE_DEFAULT_NETWORK:
21629c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    FeatureUser u = (FeatureUser)msg.obj;
21639c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    u.expire();
2164d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                    break;
21658dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_INET_CONDITION_CHANGE:
21668dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
21678dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int netType = msg.arg1;
21688dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int condition = msg.arg2;
21698dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleInetConditionChange(netType, condition);
2170d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                    break;
21718dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
21728dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_INET_CONDITION_HOLD_END:
21738dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
21748dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int netType = msg.arg1;
21758dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int sequence = msg.arg2;
21768dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleInetConditionHoldEnd(netType, sequence);
2177d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                    break;
21788dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
21798dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_SET_NETWORK_PREFERENCE:
21808dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
21818dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int preference = msg.arg1;
21828dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleSetNetworkPreference(preference);
21838dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    break;
21848dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
21858dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_SET_BACKGROUND_DATA:
21868dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
21878dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    boolean enabled = (msg.arg1 == ENABLED);
21888dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleSetBackgroundData(enabled);
21898dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    break;
21908dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
21918dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_SET_MOBILE_DATA:
21928dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
21938dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    boolean enabled = (msg.arg1 == ENABLED);
21948dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleSetMobileData(enabled);
219514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    break;
21968dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
2197434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                case EVENT_APPLY_GLOBAL_HTTP_PROXY:
2198434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                {
2199434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    handleDeprecatedGlobalHttpProxy();
2200d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    break;
2201d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                }
2202d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                case EVENT_SET_DEPENDENCY_MET:
2203d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                {
2204d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    boolean met = (msg.arg1 == ENABLED);
2205d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    handleSetDependencyMet(msg.arg2, met);
2206d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    break;
2207434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                }
220844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                case EVENT_RESTORE_DNS:
220944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                {
221044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    if (mActiveDefaultNetwork != -1) {
221144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                        handleDnsConfigurationChange(mActiveDefaultNetwork);
221244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    }
221344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    break;
221444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2218d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
2219d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // javadoc from interface
22205a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public int tether(String iface) {
2221d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        enforceTetherChangePermission();
22225a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
22235a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        if (isTetheringSupported()) {
22245a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return mTethering.tether(iface);
22255a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        } else {
22265a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
22275a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        }
2228d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
2229d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
2230d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // javadoc from interface
22315a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public int untether(String iface) {
2232d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        enforceTetherChangePermission();
22335a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
22345a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        if (isTetheringSupported()) {
22355a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return mTethering.untether(iface);
22365a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        } else {
22375a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
22385a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        }
22395a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    }
22405a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
22415a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    // javadoc from interface
22425a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public int getLastTetherError(String iface) {
22435a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        enforceTetherAccessPermission();
22445a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
22455a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        if (isTetheringSupported()) {
22465a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return mTethering.getLastTetherError(iface);
22475a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        } else {
22485a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
22495a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        }
22502a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
22512a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
22522a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // TODO - proper iface API for selection by property, inspection, etc
22532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    public String[] getTetherableUsbRegexs() {
22542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
22552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        if (isTetheringSupported()) {
22562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return mTethering.getTetherableUsbRegexs();
22572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        } else {
22582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return new String[0];
22592a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        }
22602a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
22612a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
22622a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    public String[] getTetherableWifiRegexs() {
22632a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
22642a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        if (isTetheringSupported()) {
22652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return mTethering.getTetherableWifiRegexs();
22662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        } else {
22672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return new String[0];
22686fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        }
22696fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    }
22706fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
22716fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    public String[] getTetherableBluetoothRegexs() {
22726fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        enforceTetherAccessPermission();
22736fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        if (isTetheringSupported()) {
22746fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang            return mTethering.getTetherableBluetoothRegexs();
22756fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        } else {
22766fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang            return new String[0];
22772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        }
2278d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
2279d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
22806c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood    public int setUsbTethering(boolean enable) {
22816c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        enforceTetherAccessPermission();
22826c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        if (isTetheringSupported()) {
22836c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood            return mTethering.setUsbTethering(enable);
22846c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        } else {
22856c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
22866c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        }
22876c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood    }
22886c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood
2289d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // TODO - move iface listing, queries, etc to new module
2290d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // javadoc from interface
2291d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    public String[] getTetherableIfaces() {
22922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
2293d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        return mTethering.getTetherableIfaces();
2294d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
2295d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
2296d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    public String[] getTetheredIfaces() {
22972a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
2298d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        return mTethering.getTetheredIfaces();
2299d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
23002a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
23015a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public String[] getTetheringErroredIfaces() {
23025a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        enforceTetherAccessPermission();
23035a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        return mTethering.getErroredIfaces();
23045a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    }
23055a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
23062a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // if ro.tether.denied = true we default to no tethering
23072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // gservices could set the secure setting to 1 though to enable it on a build where it
23082a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // had previously been turned off.
23092a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    public boolean isTetheringSupported() {
23102a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
23112a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
2312c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt        boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(),
2313c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt                Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0);
2314c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt        return tetherEnabledInSettings && mTetheringConfigValid;
23152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
231614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
231714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // An API NetworkStateTrackers can call when they lose their network.
231814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // This will automatically be cleared after X seconds or a network becomes CONNECTED,
231914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // whichever happens first.  The timer is started by the first caller and not
232014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // restarted by subsequent callers.
232114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    public void requestNetworkTransitionWakelock(String forWhom) {
232214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        enforceConnectivityInternalPermission();
232314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        synchronized (this) {
232414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            if (mNetTransitionWakeLock.isHeld()) return;
232514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            mNetTransitionWakeLockSerialNumber++;
232614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            mNetTransitionWakeLock.acquire();
232714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            mNetTransitionWakeLockCausedBy = forWhom;
232814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        }
232914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mHandler.sendMessageDelayed(mHandler.obtainMessage(
2330f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt                EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
233114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                mNetTransitionWakeLockSerialNumber, 0),
233214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                mNetTransitionWakeLockTimeout);
233314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        return;
233414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    }
2335ca4306c976d393c3cd04270bc2de0af2f4f30fa5Robert Greenwalt
2336d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    // 100 percent is full good, 0 is full bad.
2337d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    public void reportInetCondition(int networkType, int percentage) {
2338ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("reportNetworkCondition(" + networkType + ", " + percentage + ")");
2339d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt        mContext.enforceCallingOrSelfPermission(
2340d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                android.Manifest.permission.STATUS_BAR,
2341d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                "ConnectivityService");
2342d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt
23434e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        if (DBG) {
23444e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            int pid = getCallingPid();
23454e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            int uid = getCallingUid();
23464e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            String s = pid + "(" + uid + ") reports inet is " +
23474e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                (percentage > 50 ? "connected" : "disconnected") + " (" + percentage + ") on " +
23484e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                "network Type " + networkType + " at " + GregorianCalendar.getInstance().getTime();
23494e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            mInetLog.add(s);
23504e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            while(mInetLog.size() > INET_CONDITION_LOG_MAX_SIZE) {
23514e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                mInetLog.remove(0);
23524e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            }
23534e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        }
2354d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(
23558dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            EVENT_INET_CONDITION_CHANGE, networkType, percentage));
23568dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
23578dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
23588dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleInetConditionChange(int netType, int condition) {
23598dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (DBG) {
2360ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("Inet connectivity change, net=" +
23618dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    netType + ", condition=" + condition +
23628dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    ",mActiveDefaultNetwork=" + mActiveDefaultNetwork);
23638dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
23648dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mActiveDefaultNetwork == -1) {
2365ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("no active default network - aborting");
23668dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
23678dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
23688dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mActiveDefaultNetwork != netType) {
2369ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("given net not default - aborting");
23708dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
23718dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
23728dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mDefaultInetCondition = condition;
23738dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        int delay;
23748dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mInetConditionChangeInFlight == false) {
2375ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("starting a change hold");
23768dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            // setup a new hold to debounce this
23778dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            if (mDefaultInetCondition > 50) {
23788dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                delay = Settings.Secure.getInt(mContext.getContentResolver(),
23798dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                        Settings.Secure.INET_CONDITION_DEBOUNCE_UP_DELAY, 500);
23808dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            } else {
23818dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                delay = Settings.Secure.getInt(mContext.getContentResolver(),
23828dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                Settings.Secure.INET_CONDITION_DEBOUNCE_DOWN_DELAY, 3000);
23838dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            }
23848dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            mInetConditionChangeInFlight = true;
23858dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_INET_CONDITION_HOLD_END,
23868dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    mActiveDefaultNetwork, mDefaultConnectionSequence), delay);
23878dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        } else {
23888dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            // we've set the new condition, when this hold ends that will get
23898dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            // picked up
2390ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("currently in hold - not setting new end evt");
23918dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
23928dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
23938dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
23948dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleInetConditionHoldEnd(int netType, int sequence) {
23958dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (DBG) {
2396ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("Inet hold end, net=" + netType +
23978dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    ", condition =" + mDefaultInetCondition +
23988dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    ", published condition =" + mDefaultInetConditionPublished);
23998dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24008dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mInetConditionChangeInFlight = false;
24018dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
24028dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mActiveDefaultNetwork == -1) {
2403ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("no active default network - aborting");
24048dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
24058dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24068dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mDefaultConnectionSequence != sequence) {
2407ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("event hold for obsolete network - aborting");
24088dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
24098dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24108dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mDefaultInetConditionPublished == mDefaultInetCondition) {
2411ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("no change in condition - aborting");
24128dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
24138dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24148dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        NetworkInfo networkInfo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
24158dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (networkInfo.isConnected() == false) {
2416ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            if (DBG) log("default network not connected - aborting");
24178dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
24188dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
24198dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mDefaultInetConditionPublished = mDefaultInetCondition;
24208dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        sendInetConditionBroadcast(networkInfo);
24218dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        return;
2422d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    }
2423434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2424434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    public synchronized ProxyProperties getProxy() {
2425434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (mGlobalProxy != null) return mGlobalProxy;
2426434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (mDefaultProxy != null) return mDefaultProxy;
2427434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        return null;
2428434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2429434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2430434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    public void setGlobalProxy(ProxyProperties proxyProperties) {
2431434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        enforceChangePermission();
2432434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        synchronized (mGlobalProxyLock) {
2433434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (proxyProperties == mGlobalProxy) return;
2434434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
2435434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
2436434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2437434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String host = "";
2438434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            int port = 0;
2439434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String exclList = "";
2440434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (proxyProperties != null && !TextUtils.isEmpty(proxyProperties.getHost())) {
2441434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mGlobalProxy = new ProxyProperties(proxyProperties);
2442434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                host = mGlobalProxy.getHost();
2443434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                port = mGlobalProxy.getPort();
2444434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                exclList = mGlobalProxy.getExclusionList();
2445434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            } else {
2446434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mGlobalProxy = null;
2447434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            }
2448434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            ContentResolver res = mContext.getContentResolver();
2449434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            Settings.Secure.putString(res, Settings.Secure.GLOBAL_HTTP_PROXY_HOST, host);
2450434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            Settings.Secure.putInt(res, Settings.Secure.GLOBAL_HTTP_PROXY_PORT, port);
2451b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            Settings.Secure.putString(res, Settings.Secure.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
2452434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    exclList);
2453434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2454434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2455434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (mGlobalProxy == null) {
2456434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            proxyProperties = mDefaultProxy;
2457434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2458434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        sendProxyBroadcast(proxyProperties);
2459434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2460434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2461b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt    private void loadGlobalProxy() {
2462b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        ContentResolver res = mContext.getContentResolver();
2463b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        String host = Settings.Secure.getString(res, Settings.Secure.GLOBAL_HTTP_PROXY_HOST);
2464b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        int port = Settings.Secure.getInt(res, Settings.Secure.GLOBAL_HTTP_PROXY_PORT, 0);
2465b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        String exclList = Settings.Secure.getString(res,
2466b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt                Settings.Secure.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
2467b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        if (!TextUtils.isEmpty(host)) {
2468b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            ProxyProperties proxyProperties = new ProxyProperties(host, port, exclList);
2469b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            synchronized (mGlobalProxyLock) {
2470b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt                mGlobalProxy = proxyProperties;
2471b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            }
2472b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        }
2473b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt    }
2474b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt
2475434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    public ProxyProperties getGlobalProxy() {
2476434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        synchronized (mGlobalProxyLock) {
2477434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            return mGlobalProxy;
2478434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2479434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2480434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2481434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private void handleApplyDefaultProxy(int type) {
2482434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        // check if new default - push it out to all VM if so
2483434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        ProxyProperties proxy = mNetTrackers[type].getLinkProperties().getHttpProxy();
2484434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        synchronized (this) {
2485434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
2486434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (mDefaultProxy == proxy) return;
2487434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (!TextUtils.isEmpty(proxy.getHost())) {
2488434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mDefaultProxy = proxy;
2489434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            } else {
2490434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mDefaultProxy = null;
2491434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            }
2492434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2493ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("changing default proxy to " + proxy);
2494434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if ((proxy == null && mGlobalProxy == null) || proxy.equals(mGlobalProxy)) return;
2495434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (mGlobalProxy != null) return;
2496434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        sendProxyBroadcast(proxy);
2497434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2498434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2499434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private void handleDeprecatedGlobalHttpProxy() {
2500434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        String proxy = Settings.Secure.getString(mContext.getContentResolver(),
2501434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                Settings.Secure.HTTP_PROXY);
2502434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (!TextUtils.isEmpty(proxy)) {
2503434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String data[] = proxy.split(":");
2504434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String proxyHost =  data[0];
2505434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            int proxyPort = 8080;
2506434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (data.length > 1) {
2507434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                try {
2508434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    proxyPort = Integer.parseInt(data[1]);
2509434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                } catch (NumberFormatException e) {
2510434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    return;
2511434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                }
2512434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            }
2513434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            ProxyProperties p = new ProxyProperties(data[0], proxyPort, "");
2514434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            setGlobalProxy(p);
2515434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2516434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2517434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2518434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private void sendProxyBroadcast(ProxyProperties proxy) {
251955985bed7be8c93296eee3f4f39557fba4fbaebeRobert Greenwalt        if (proxy == null) proxy = new ProxyProperties("", 0, "");
2520ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        log("sending Proxy Broadcast for " + proxy);
2521434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
2522b35d67a8a773f2d3127a119b424a86b3e56fe563Stan Chesnutt        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
2523b35d67a8a773f2d3127a119b424a86b3e56fe563Stan Chesnutt            Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2524434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
2525a2e13392412d5094e49ea0053599477401d1a67eRobert Greenwalt        mContext.sendStickyBroadcast(intent);
2526434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2527434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2528434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private static class SettingsObserver extends ContentObserver {
2529434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        private int mWhat;
2530434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        private Handler mHandler;
2531434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        SettingsObserver(Handler handler, int what) {
2532434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            super(handler);
2533434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            mHandler = handler;
2534434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            mWhat = what;
2535434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2536434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2537434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        void observe(Context context) {
2538434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            ContentResolver resolver = context.getContentResolver();
2539434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            resolver.registerContentObserver(Settings.Secure.getUriFor(
2540434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    Settings.Secure.HTTP_PROXY), false, this);
2541434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2542434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
2543434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        @Override
2544434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        public void onChange(boolean selfChange) {
2545434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            mHandler.obtainMessage(mWhat).sendToTarget();
2546434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
2547434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
2548ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville
2549ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    private void log(String s) {
2550ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        Slog.d(TAG, s);
2551ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    }
2552ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville
2553ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    private void loge(String s) {
2554ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        Slog.e(TAG, s);
2555ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    }
2556ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
25572b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville    int convertFeatureToNetworkType(String feature){
25582b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        int networkType = -1;
25592b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
25602b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville            networkType = ConnectivityManager.TYPE_MOBILE_MMS;
25612b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
25622b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville            networkType = ConnectivityManager.TYPE_MOBILE_SUPL;
25632b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
25642b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville                TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
25652b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville            networkType = ConnectivityManager.TYPE_MOBILE_DUN;
25662b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
25672b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville            networkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
25682b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_FOTA)) {
25692b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville            networkType = ConnectivityManager.TYPE_MOBILE_FOTA;
25702b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_IMS)) {
25712b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville            networkType = ConnectivityManager.TYPE_MOBILE_IMS;
25722b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_CBS)) {
25732b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville            networkType = ConnectivityManager.TYPE_MOBILE_CBS;
25742b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        }
25752b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville        return networkType;
25762b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville    }
2577c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
2578c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private static <T> T checkNotNull(T value, String message) {
2579c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        if (value == null) {
2580c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            throw new NullPointerException(message);
2581c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
2582c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return value;
2583c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
2584ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
258504ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    /**
258604ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * Protect a socket from VPN routing rules. This method is used by
25872e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * VpnBuilder and not available in ConnectivityManager. Permissions
25882e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * are checked in Vpn class.
258904ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * @hide
259004ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     */
2591ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    @Override
25925779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh    public boolean protectVpn(ParcelFileDescriptor socket) {
25935779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        try {
25945779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            int type = mActiveDefaultNetwork;
25955779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            if (ConnectivityManager.isNetworkTypeValid(type)) {
25965779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                mVpn.protect(socket, mNetTrackers[type].getLinkProperties().getInterfaceName());
25975779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                return true;
25985779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            }
25995779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        } catch (Exception e) {
26005779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            // ignore
26015779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        } finally {
26025779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            try {
26035779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                socket.close();
26045779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            } catch (Exception e) {
26055779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                // ignore
26065779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            }
26075779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        }
26085779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        return false;
2609ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
2610ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
261104ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    /**
261204ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * Prepare for a VPN application. This method is used by VpnDialogs
26132e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * and not available in ConnectivityManager. Permissions are checked
26142e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * in Vpn class.
261504ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * @hide
261604ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     */
2617ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    @Override
2618100155a310fbb5028fc48e359bdfb7c4d3531843Chia-chi Yeh    public boolean prepareVpn(String oldPackage, String newPackage) {
2619100155a310fbb5028fc48e359bdfb7c4d3531843Chia-chi Yeh        return mVpn.prepare(oldPackage, newPackage);
2620ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
2621ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
262204ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    /**
262304ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * Configure a TUN interface and return its file descriptor. Parameters
262404ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * are encoded and opaque to this class. This method is used by VpnBuilder
26252e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * and not available in ConnectivityManager. Permissions are checked in
26262e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Vpn class.
262704ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * @hide
262804ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     */
2629ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    @Override
263004ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    public ParcelFileDescriptor establishVpn(VpnConfig config) {
2631ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        return mVpn.establish(config);
2632ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
2633ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
263477fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh    /**
26352e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Start legacy VPN and return an intent to VpnDialogs. This method is
26362e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * used by VpnSettings and not available in ConnectivityManager.
26372e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Permissions are checked in Vpn class.
26382e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * @hide
26392e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     */
26402e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    @Override
26412e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    public void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
26422e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh        mVpn.startLegacyVpn(config, racoon, mtpd);
26432e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    }
26442e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh
26452e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    /**
26462e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Return the information of the ongoing legacy VPN. This method is used
26472e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * by VpnSettings and not available in ConnectivityManager. Permissions
26482e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * are checked in Vpn class.
264977fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh     * @hide
265077fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh     */
265177fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh    @Override
26522e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    public LegacyVpnInfo getLegacyVpnInfo() {
26532e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh        return mVpn.getLegacyVpnInfo();
265477fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh    }
265577fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh
2656ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    /**
2657ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * Callback for VPN subsystem. Currently VPN is not adapted to the service
2658ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * through NetworkStateTracker since it works differently. For example, it
2659ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * needs to override DNS servers but never takes the default routes. It
2660ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * relies on another data network, and it could keep existing connections
2661ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * alive after reconnecting, switching between networks, or even resuming
2662ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * from deep sleep. Calls from applications should be done synchronously
2663ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * to avoid race conditions. As these are all hidden APIs, refactoring can
2664ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * be done whenever a better abstraction is developed.
2665ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     */
2666ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    public class VpnCallback {
2667ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
2668ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        private VpnCallback() {
2669ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        }
2670ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
267144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        public void override(List<String> dnsServers, List<String> searchDomains) {
267244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (dnsServers == null) {
267344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                restore();
267444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                return;
267544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
267644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
267744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // Convert DNS servers into addresses.
267844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            List<InetAddress> addresses = new ArrayList<InetAddress>();
267944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            for (String address : dnsServers) {
268044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                // Double check the addresses and remove invalid ones.
268144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                try {
268244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    addresses.add(InetAddress.parseNumericAddress(address));
268344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                } catch (Exception e) {
268444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    // ignore
268544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
268644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
268744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (addresses.isEmpty()) {
268844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                restore();
268944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                return;
269044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
269144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
269244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // Concatenate search domains into a string.
269344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            StringBuilder buffer = new StringBuilder();
269444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (searchDomains != null) {
269544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                for (String domain : searchDomains) {
269644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    buffer.append(domain).append(' ');
269744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
269844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
269944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            String domains = buffer.toString().trim();
270044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
270144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // Apply DNS changes.
270244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            boolean changed = false;
270344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            synchronized (mDnsLock) {
2704a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                changed = updateDns("VPN", "VPN", addresses, domains);
270544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                mDnsOverridden = true;
270644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
270744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (changed) {
270844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                bumpDns();
270944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
271044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
271144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // TODO: temporarily remove http proxy?
2712ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        }
2713ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
271444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        public void restore() {
271544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            synchronized (mDnsLock) {
271644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                if (!mDnsOverridden) {
271744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    return;
271844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
271944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                mDnsOverridden = false;
272044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
272144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
2722ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        }
2723ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
27249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2725