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
1969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport static android.Manifest.permission.CONNECTIVITY_INTERNAL;
201a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkeyimport static android.Manifest.permission.MANAGE_NETWORK_POLICY;
21db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Baiimport static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
22961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkeyimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
23961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkeyimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
24fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.TYPE_BLUETOOTH;
25fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.TYPE_DUMMY;
26fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.TYPE_ETHERNET;
27fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.TYPE_MOBILE;
28fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI;
29fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIMAX;
30fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkeyimport static android.net.ConnectivityManager.getNetworkTypeName;
31c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.ConnectivityManager.isNetworkTypeValid;
32c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
33fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
34c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
359538bdd3c77968c7673719c580ae653ede4654d6Irfan Sheriffimport android.app.Activity;
3615c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganeshimport android.bluetooth.BluetoothTetheringDataTracker;
3769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport android.content.BroadcastReceiver;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
40148c7d0de720a92632aa6ed10a39bfc38b427239tk.munimport android.content.ContextWrapper;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
4269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport android.content.IntentFilter;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
44148c7d0de720a92632aa6ed10a39bfc38b427239tk.munimport android.content.res.Resources;
45434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwaltimport android.database.ContentObserver;
46da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriffimport android.net.CaptivePortalTracker;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.ConnectivityManager;
48da3d5e6587c1476d489495ac93e84ebf223024c9Robert Greenwaltimport android.net.DummyDataStateTracker;
491997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.net.EthernetDataTracker;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.IConnectivityManager;
51db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Baiimport android.net.INetworkManagementEventObserver;
52c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.INetworkPolicyListener;
53c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.INetworkPolicyManager;
54367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport android.net.INetworkStatsService;
55c9822c5aeae833bb4a586c7af8a7b2641e8c17aeWink Savilleimport android.net.LinkAddress;
5615c7439acb22ab079dd2ebe42bdf0d2ffd525c5dJaikumar Ganeshimport android.net.LinkProperties;
570a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwaltimport android.net.LinkProperties.CompareResult;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.MobileDataStateTracker;
59d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwaltimport android.net.NetworkConfig;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.NetworkInfo;
61c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.NetworkInfo.DetailedState;
62f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkeyimport android.net.NetworkQuotaInfo;
63d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkState;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.NetworkStateTracker;
65585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwaltimport android.net.NetworkUtils;
66434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwaltimport android.net.Proxy;
67434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwaltimport android.net.ProxyProperties;
68aa70f101e08098ed9cb190abe2d7f952561026b8Robert Greenwaltimport android.net.RouteInfo;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.wifi.WifiStateTracker;
70148c7d0de720a92632aa6ed10a39bfc38b427239tk.munimport android.net.wimax.WimaxManagerConstants;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
72da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwoodimport android.os.FileUtils;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
74bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Savilleimport android.os.HandlerThread;
7542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.os.IBinder;
76c9338305bf4d5cfb9ec2a1d64144d8cef32a00a5Chia-chi Yehimport android.os.INetworkManagementService;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
79ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yehimport android.os.ParcelFileDescriptor;
8014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwaltimport android.os.PowerManager;
81f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkeyimport android.os.Process;
8242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.os.RemoteException;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager;
845a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwaltimport android.os.SystemClock;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties;
865ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings;
8869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport android.security.Credentials;
8982f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkeyimport android.security.KeyStore;
9042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.text.TextUtils;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog;
928a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
93c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.util.SparseIntArray;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
952e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yehimport com.android.internal.net.LegacyVpnInfo;
9604ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yehimport com.android.internal.net.VpnConfig;
9782f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkeyimport com.android.internal.net.VpnProfile;
9842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport com.android.internal.telephony.Phone;
99a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Savilleimport com.android.internal.telephony.PhoneConstants;
100e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkeyimport com.android.internal.util.IndentingPrintWriter;
1011059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport com.android.server.am.BatteryStatsService;
102d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwaltimport com.android.server.connectivity.Tethering;
103ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yehimport com.android.server.connectivity.Vpn;
104216c181e76ee11a47a0b2a180f9af96740ab38adJeff Sharkeyimport com.android.server.net.BaseNetworkObserver;
10569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport com.android.server.net.LockdownVpnTracker;
106d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport com.google.android.collect.Lists;
107fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport com.google.android.collect.Sets;
108fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
109148c7d0de720a92632aa6ed10a39bfc38b427239tk.munimport dalvik.system.DexClassLoader;
110fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
112d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriffimport java.io.IOException;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
114148c7d0de720a92632aa6ed10a39bfc38b427239tk.munimport java.lang.reflect.Constructor;
115c9822c5aeae833bb4a586c7af8a7b2641e8c17aeWink Savilleimport java.net.Inet4Address;
116e822225f7a01ef088ff01f7613f953d5d89945edWink Savilleimport java.net.Inet6Address;
11747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.InetAddress;
11847f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.net.UnknownHostException;
11942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport java.util.ArrayList;
120fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport java.util.Arrays;
12147f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwaltimport java.util.Collection;
1224e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwaltimport java.util.GregorianCalendar;
123fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport java.util.HashSet;
12442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport java.util.List;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ConnectivityService extends IConnectivityManager.Stub {
130899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey    private static final String TAG = "ConnectivityService";
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
132ba175a5e1331883ef4ecfc2b751789a3492efca1Robert Greenwalt    private static final boolean DBG = true;
133c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville    private static final boolean VDBG = false;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
135c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private static final boolean LOGD_RULES = false;
136c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
137899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey    // TODO: create better separation between radio types and network types
138899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey
13942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // how long to wait before switching back to a radio's default network
14042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
14142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // system property that can override the above value
14242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
14342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            "android.telephony.apn-restore";
14442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
145f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    // used in recursive route setting to add gateways for the host for which
146f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    // a host route was requested.
147f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt    private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
148f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
149d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    private Tethering mTethering;
150c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt    private boolean mTetheringConfigValid = false;
151d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
15269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    private KeyStore mKeyStore;
15382f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey
154ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    private Vpn mVpn;
155899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey    private VpnCallback mVpnCallback = new VpnCallback();
156ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
15769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    private boolean mLockdownEnabled;
15869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    private LockdownVpnTracker mLockdownTracker;
15969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
160fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    /** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
161fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private Object mRulesLock = new Object();
162c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    /** Currently active network rules by UID. */
163c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private SparseIntArray mUidRules = new SparseIntArray();
164fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    /** Set of ifaces that are costly. */
165fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private HashSet<String> mMeteredIfaces = Sets.newHashSet();
166c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sometimes we want to refer to the individual network state
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * trackers separately, and sometimes we just want to treat them
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * abstractly.
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private NetworkStateTracker mNetTrackers[];
17342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
174da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    /* Handles captive portal check on a network */
175da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    private CaptivePortalTracker mCaptivePortalTracker;
176da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff
17742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    /**
178e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     * The link properties that define the current links
179e822225f7a01ef088ff01f7613f953d5d89945edWink Saville     */
180e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    private LinkProperties mCurrentLinkProperties[];
181e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
182e822225f7a01ef088ff01f7613f953d5d89945edWink Saville    /**
18342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * A per Net list of the PID's that requested access to the net
18442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * used both as a refcount and for per-PID DNS selection
18542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     */
18642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private List mNetRequestersPids[];
18742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
18842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // priority order of the nettrackers
18942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // (excluding dynamically set mNetworkPreference)
19042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // TODO - move mNetworkTypePreference into this
19142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private int[] mPriorityList;
19242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context mContext;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mNetworkPreference;
19542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private int mActiveDefaultNetwork = -1;
196d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    // 0 is full bad, 100 is full good
197d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private int mDefaultInetCondition = 0;
198d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private int mDefaultInetConditionPublished = 0;
199d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private boolean mInetConditionChangeInFlight = false;
200d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    private int mDefaultConnectionSequence = 0;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    private Object mDnsLock = new Object();
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mNumDnsEntries;
20444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    private boolean mDnsOverridden = false;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mTestMode;
20700092874b1fea2354b6a3048974abfc4bba69258Joe Onorato    private static ConnectivityService sServiceInstance;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    private INetworkManagementService mNetd;
210c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private INetworkPolicyManager mPolicyManager;
21159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
2128dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int ENABLED  = 1;
2138dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private static final int DISABLED = 0;
2148dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2153b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt    private static final boolean ADD = true;
2163b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt    private static final boolean REMOVE = false;
2173b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt
2183b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt    private static final boolean TO_DEFAULT_TABLE = true;
2193b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt    private static final boolean TO_SECONDARY_TABLE = false;
2203b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt
2218dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2228dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally as a delayed event to make us switch back to the
2238dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * default network
2248dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2254c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_RESTORE_DEFAULT_NETWORK = 1;
2268dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2278dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2288dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to change our mobile data enabled flag
2298dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2304c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_CHANGE_MOBILE_DATA_ENABLED = 2;
2318dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2328dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2338dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to change our network preference setting
2348dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = networkType to prefer
2358dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2364c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_SET_NETWORK_PREFERENCE = 3;
2378dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2388dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2398dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to synchronize inet condition reports
2408dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = networkType
2418dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg2 = condition (0 bad, 100 good)
2428dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2434c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_INET_CONDITION_CHANGE = 4;
2448dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2458dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2468dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to mark the end of inet condition hold periods
2478dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = networkType
2488dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2494c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_INET_CONDITION_HOLD_END = 5;
2508dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
2518dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    /**
2528dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * used internally to set enable/disable cellular data
2538dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     * arg1 = ENBALED or DISABLED
2548dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt     */
2554c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_SET_MOBILE_DATA = 7;
2568dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
257f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt    /**
258f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt     * used internally to clear a wakelock when transitioning
259f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt     * from one net to another
260f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt     */
2614c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
262f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt
263434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    /**
264434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt     * used internally to reload global proxy settings
265434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt     */
2664c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
267434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
268d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    /**
269d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     * used internally to set external dependency met/unmet
270d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     * arg1 = ENABLED (met) or DISABLED (unmet)
271d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     * arg2 = NetworkType
272d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt     */
2734c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_SET_DEPENDENCY_MET = 10;
274d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt
27544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    /**
27644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh     * used internally to restore DNS properties back to the
27744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh     * default network
27844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh     */
2794c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_RESTORE_DNS = 11;
28044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
2812b30afdbad5e79c5775ac9756f3b986268d90f1fWink Saville    /**
282628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville     * used internally to send a sticky broadcast delayed.
283628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville     */
2844c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_SEND_STICKY_BROADCAST_INTENT = 12;
285628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
2868e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    /**
2878e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey     * Used internally to
2888e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey     * {@link NetworkStateTracker#setPolicyDataEnable(boolean)}.
2898e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey     */
2904c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private static final int EVENT_SET_POLICY_DATA_ENABLE = 13;
2918e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
29269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    private static final int EVENT_VPN_STATE_CHANGED = 14;
29369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
2944c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    /** Handler used for internal events. */
2954c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private InternalHandler mHandler;
2964c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    /** Handler used for incoming {@link NetworkStateTracker} events. */
2974c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private NetworkStateTrackerHandler mTrackerHandler;
29842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
29942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // list of DeathRecipients used to make sure features are turned off when
30042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // a process dies
3013bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo    private List<FeatureUser> mFeatureUsers;
30242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
3030f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    private boolean mSystemReady;
3041c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn    private Intent mInitialBroadcast;
3050f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood
30614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private PowerManager.WakeLock mNetTransitionWakeLock;
30714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private String mNetTransitionWakeLockCausedBy = "";
30814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private int mNetTransitionWakeLockSerialNumber;
30914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private int mNetTransitionWakeLockTimeout;
31014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
311e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt    private InetAddress mDefaultDns;
312e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt
3130a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    // this collection is used to refcount the added routes - if there are none left
3140a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    // it's time to remove the route from the route table
3150a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private Collection<RouteInfo> mAddedRoutes = new ArrayList<RouteInfo>();
3160a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
3174e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt    // used in DBG mode to track inet condition reports
3184e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt    private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
3194e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt    private ArrayList mInetLog;
3204e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt
321434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    // track the current default http proxy - tell the world if we get a new one (real change)
322434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private ProxyProperties mDefaultProxy = null;
3234c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh    private Object mDefaultProxyLock = new Object();
3244c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh    private boolean mDefaultProxyDisabled = false;
3254c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh
326434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    // track the global proxy.
327434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private ProxyProperties mGlobalProxy = null;
328434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private final Object mGlobalProxyLock = new Object();
329434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
330434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private SettingsObserver mSettingsObserver;
331434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
332d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    NetworkConfig[] mNetConfigs;
3335154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt    int mNetworksDefined;
33442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
335511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt    private static class RadioAttributes {
33642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public int mSimultaneity;
33742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public int mType;
33842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public RadioAttributes(String init) {
33942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            String fragments[] = init.split(",");
3405154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            mType = Integer.parseInt(fragments[0]);
3415154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            mSimultaneity = Integer.parseInt(fragments[1]);
34242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
34342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
34442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    RadioAttributes[] mRadioAttributes;
34542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
34650393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt    // the set of network types that can only be enabled by system/sig apps
34750393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt    List mProtectedNetworks;
34850393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
349367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    public ConnectivityService(Context context, INetworkManagementService netd,
350367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            INetworkStatsService statsService, INetworkPolicyManager policyManager) {
351fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        // Currently, omitting a NetworkFactory will create one internally
352fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        // TODO: create here when we have cleaner WiMAX support
353fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        this(context, netd, statsService, policyManager, null);
354fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    }
355fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
356899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey    public ConnectivityService(Context context, INetworkManagementService netManager,
357fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            INetworkStatsService statsService, INetworkPolicyManager policyManager,
358fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            NetworkFactory netFactory) {
359ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("ConnectivityService starting up");
360de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt
361bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
362bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        handlerThread.start();
3634c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        mHandler = new InternalHandler(handlerThread.getLooper());
3644c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        mTrackerHandler = new NetworkStateTrackerHandler(handlerThread.getLooper());
365bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville
366fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        if (netFactory == null) {
367fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            netFactory = new DefaultNetworkFactory(context, mTrackerHandler);
368fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        }
369fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
370de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt        // setup our unique device name
371733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt        if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
372733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt            String id = Settings.Secure.getString(context.getContentResolver(),
373733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt                    Settings.Secure.ANDROID_ID);
374733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt            if (id != null && id.length() > 0) {
375a10a3ad35afc0b2a97cd72afceebd8e3db9b7db4Irfan Sheriff                String name = new String("android-").concat(id);
376733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt                SystemProperties.set("net.hostname", name);
377733c62909c1cca72be50094acb15dc1014b956ceRobert Greenwalt            }
378de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt        }
379de8383ca312c03fa8e935ac1549ae31ce668652cRobert Greenwalt
380e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        // read our default dns server ip
381625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey        String dns = Settings.Global.getString(context.getContentResolver(),
382625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                Settings.Global.DEFAULT_DNS_SERVER);
383e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        if (dns == null || dns.length() == 0) {
384e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt            dns = context.getResources().getString(
385e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt                    com.android.internal.R.string.config_default_dns_server);
386e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        }
387e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        try {
388e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt            mDefaultDns = NetworkUtils.numericToInetAddress(dns);
389e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt        } catch (IllegalArgumentException e) {
390ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            loge("Error setting defaultDns using " + dns);
391e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt        }
392e90aa5e97e3a5502a8334ed6ceb98305f6e01361Robert Greenwalt
393c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        mContext = checkNotNull(context, "missing Context");
394899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey        mNetd = checkNotNull(netManager, "missing INetworkManagementService");
395c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
39682f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        mKeyStore = KeyStore.getInstance();
39714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
398c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        try {
399c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            mPolicyManager.registerListener(mPolicyListener);
400c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        } catch (RemoteException e) {
401c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // ouch, no rules updates means some processes may never get network
40258d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            loge("unable to register INetworkPolicyListener" + e.toString());
403c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
404c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
405c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final PowerManager powerManager = (PowerManager) context.getSystemService(
406c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                Context.POWER_SERVICE);
40714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
40814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
40914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                com.android.internal.R.integer.config_networkTransitionTimeout);
41014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
41142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        mNetTrackers = new NetworkStateTracker[
41242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                ConnectivityManager.MAX_NETWORK_TYPE+1];
413e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
41486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNetworkPreference = getPersistedNetworkPreference();
41686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
4175154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mRadioAttributes = new RadioAttributes[ConnectivityManager.MAX_RADIO_TYPE+1];
418d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
4195154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt
42042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // Load device network attributes from resources
42142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String[] raStrings = context.getResources().getStringArray(
42242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                com.android.internal.R.array.radioAttributes);
4235154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (String raString : raStrings) {
4245154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            RadioAttributes r = new RadioAttributes(raString);
4255154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {
426ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);
4275154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                continue;
4285154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
4295154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (mRadioAttributes[r.mType] != null) {
430ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Error in radioAttributes - ignoring attempt to redefine type " +
4315154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                        r.mType);
4325154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                continue;
4335154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
43442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mRadioAttributes[r.mType] = r;
43542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
43642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
4375154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        String[] naStrings = context.getResources().getStringArray(
4385154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                com.android.internal.R.array.networkAttributes);
4395154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (String naString : naStrings) {
4405154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            try {
441d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                NetworkConfig n = new NetworkConfig(naString);
442975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
443ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    loge("Error in networkAttributes - ignoring attempt to define type " +
444975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            n.type);
4455154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    continue;
4465154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                }
447975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                if (mNetConfigs[n.type] != null) {
448ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    loge("Error in networkAttributes - ignoring attempt to redefine type " +
449975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            n.type);
4505154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    continue;
4515154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                }
452975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                if (mRadioAttributes[n.radio] == null) {
453ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    loge("Error in networkAttributes - ignoring attempt to use undefined " +
454975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            "radio " + n.radio + " in network type " + n.type);
4555154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    continue;
4565154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                }
457975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                mNetConfigs[n.type] = n;
4585154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                mNetworksDefined++;
4595154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            } catch(Exception e) {
4605154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                // ignore it - leave the entry null
4615154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
4625154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        }
4635154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt
46450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        mProtectedNetworks = new ArrayList<Integer>();
46550393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        int[] protectedNetworks = context.getResources().getIntArray(
46650393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt                com.android.internal.R.array.config_protectedNetworks);
46750393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        for (int p : protectedNetworks) {
46850393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
46950393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt                mProtectedNetworks.add(p);
47050393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            } else {
47150393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt                if (DBG) loge("Ignoring protectedNetwork " + p);
47250393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            }
47350393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        }
47450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
47542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // high priority first
4765154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mPriorityList = new int[mNetworksDefined];
47742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        {
4785154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            int insertionPoint = mNetworksDefined-1;
4795154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            int currentLowest = 0;
4805154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            int nextLowest = 0;
4815154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            while (insertionPoint > -1) {
482d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                for (NetworkConfig na : mNetConfigs) {
4835154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                    if (na == null) continue;
484975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                    if (na.priority < currentLowest) continue;
485975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                    if (na.priority > currentLowest) {
486975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                        if (na.priority < nextLowest || nextLowest == 0) {
487975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                            nextLowest = na.priority;
4885154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                        }
4895154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                        continue;
49042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
491975c8488a3667efc24a1ad5da15d571d9615020fWink Saville                    mPriorityList[insertionPoint--] = na.type;
49242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
4935154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                currentLowest = nextLowest;
4945154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                nextLowest = 0;
49542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
49642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
49742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
4985154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mNetRequestersPids = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE+1];
4995154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        for (int i : mPriorityList) {
50042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mNetRequestersPids[i] = new ArrayList();
50142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
50242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
5033bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        mFeatureUsers = new ArrayList<FeatureUser>();
50442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
5055154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mNumDnsEntries = 0;
5065154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt
5075154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        mTestMode = SystemProperties.get("cm.test.mode").equals("true")
5085154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                && SystemProperties.get("ro.build.type").equals("eng");
509fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
510fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        // Create and start trackers for hard-coded networks
511fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        for (int targetNetworkType : mPriorityList) {
512fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            final NetworkConfig config = mNetConfigs[targetNetworkType];
513fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            final NetworkStateTracker tracker;
514fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            try {
515fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                tracker = netFactory.createTracker(targetNetworkType, config);
516fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                mNetTrackers[targetNetworkType] = tracker;
517fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            } catch (IllegalArgumentException e) {
518fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                Slog.e(TAG, "Problem creating " + getNetworkTypeName(targetNetworkType)
519fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                        + " tracker: " + e);
5205154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                continue;
5215154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
522fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
523fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            tracker.startMonitoring(context, mTrackerHandler);
524fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            if (config.isDefault()) {
525fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                tracker.reconnect();
5266537b028757af736ff53a13488de4fa75aaef9a9Robert Greenwalt            }
5275154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt        }
528d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
529fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        mTethering = new Tethering(mContext, mNetd, statsService, this, mHandler.getLooper());
530ccf83af1017b7b1eaf12f6ec3d2cb2137a7cdda9Robert Greenwalt        mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
5316fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                  mTethering.getTetherableWifiRegexs().length != 0 ||
5326fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang                                  mTethering.getTetherableBluetoothRegexs().length != 0) &&
533ccf83af1017b7b1eaf12f6ec3d2cb2137a7cdda9Robert Greenwalt                                 mTethering.getUpstreamIfaceTypes().length != 0);
534c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt
535899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey        mVpn = new Vpn(mContext, mVpnCallback, mNetd);
536899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey        mVpn.startMonitoring(mContext, mTrackerHandler);
537ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
538008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh        try {
539fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            mNetd.registerObserver(mTethering);
540fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            mNetd.registerObserver(mDataActivityObserver);
541008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh        } catch (RemoteException e) {
542008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh            loge("Error registering observer :" + e);
543008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh        }
544008ff39b7cb1a1f80f29595459fd82a55ce52b83Chia-chi Yeh
5454e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        if (DBG) {
5464e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            mInetLog = new ArrayList();
5474e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        }
548434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
549434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        mSettingsObserver = new SettingsObserver(mHandler, EVENT_APPLY_GLOBAL_HTTP_PROXY);
550434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        mSettingsObserver.observe(mContext);
551b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt
5529538bdd3c77968c7673719c580ae653ede4654d6Irfan Sheriff        mCaptivePortalTracker = CaptivePortalTracker.makeCaptivePortalTracker(mContext, this);
553b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        loadGlobalProxy();
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5554c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey
556fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    /**
557fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey     * Factory that creates {@link NetworkStateTracker} instances using given
558fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey     * {@link NetworkConfig}.
559fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey     */
560fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    public interface NetworkFactory {
561fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config);
562fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    }
563fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
564fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private static class DefaultNetworkFactory implements NetworkFactory {
565fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        private final Context mContext;
566fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        private final Handler mTrackerHandler;
567fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
568fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        public DefaultNetworkFactory(Context context, Handler trackerHandler) {
569fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            mContext = context;
570fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            mTrackerHandler = trackerHandler;
571fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        }
572fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
573fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        @Override
574fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config) {
575fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            switch (config.radio) {
576fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                case TYPE_WIFI:
577fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                    return new WifiStateTracker(targetNetworkType, config.name);
578fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                case TYPE_MOBILE:
579fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                    return new MobileDataStateTracker(targetNetworkType, config.name);
580fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                case TYPE_DUMMY:
581fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                    return new DummyDataStateTracker(targetNetworkType, config.name);
582fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                case TYPE_BLUETOOTH:
583fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                    return BluetoothTetheringDataTracker.getInstance();
584fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                case TYPE_WIMAX:
585fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                    return makeWimaxStateTracker(mContext, mTrackerHandler);
586fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                case TYPE_ETHERNET:
587fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                    return EthernetDataTracker.getInstance();
588fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                default:
589fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                    throw new IllegalArgumentException(
590fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                            "Trying to create a NetworkStateTracker for an unknown radio type: "
591fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                            + config.radio);
592fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            }
593fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        }
594fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    }
595fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey
596fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    /**
597fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey     * Loads external WiMAX library and registers as system service, returning a
598fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey     * {@link NetworkStateTracker} for WiMAX. Caller is still responsible for
599fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey     * invoking {@link NetworkStateTracker#startMonitoring(Context, Handler)}.
600fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey     */
601fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private static NetworkStateTracker makeWimaxStateTracker(
602fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey            Context context, Handler trackerHandler) {
6034c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        // Initialize Wimax
604148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        DexClassLoader wimaxClassLoader;
605148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        Class wimaxStateTrackerClass = null;
606148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        Class wimaxServiceClass = null;
607148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        Class wimaxManagerClass;
608148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        String wimaxJarLocation;
609148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        String wimaxLibLocation;
610148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        String wimaxManagerClassName;
611148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        String wimaxServiceClassName;
612148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        String wimaxStateTrackerClassName;
613148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
614148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        NetworkStateTracker wimaxStateTracker = null;
615148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
616fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        boolean isWimaxEnabled = context.getResources().getBoolean(
617148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                com.android.internal.R.bool.config_wimaxEnabled);
618148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
619148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        if (isWimaxEnabled) {
620148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun            try {
621fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                wimaxJarLocation = context.getResources().getString(
622148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                        com.android.internal.R.string.config_wimaxServiceJarLocation);
623fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                wimaxLibLocation = context.getResources().getString(
624148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                        com.android.internal.R.string.config_wimaxNativeLibLocation);
625fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                wimaxManagerClassName = context.getResources().getString(
626148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                        com.android.internal.R.string.config_wimaxManagerClassname);
627fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                wimaxServiceClassName = context.getResources().getString(
628148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                        com.android.internal.R.string.config_wimaxServiceClassname);
629fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                wimaxStateTrackerClassName = context.getResources().getString(
630148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                        com.android.internal.R.string.config_wimaxStateTrackerClassname);
631148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
6327ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn                if (DBG) log("wimaxJarLocation: " + wimaxJarLocation);
633148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                wimaxClassLoader =  new DexClassLoader(wimaxJarLocation,
634fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                        new ContextWrapper(context).getCacheDir().getAbsolutePath(),
635148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                        wimaxLibLocation, ClassLoader.getSystemClassLoader());
636148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
637148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                try {
638148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                    wimaxManagerClass = wimaxClassLoader.loadClass(wimaxManagerClassName);
639148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                    wimaxStateTrackerClass = wimaxClassLoader.loadClass(wimaxStateTrackerClassName);
640148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                    wimaxServiceClass = wimaxClassLoader.loadClass(wimaxServiceClassName);
641148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                } catch (ClassNotFoundException ex) {
642148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                    loge("Exception finding Wimax classes: " + ex.toString());
643148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                    return null;
644148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                }
645148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun            } catch(Resources.NotFoundException ex) {
646148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                loge("Wimax Resources does not exist!!! ");
647148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                return null;
648148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun            }
649148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
650148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun            try {
6517ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn                if (DBG) log("Starting Wimax Service... ");
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
653148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                Constructor wmxStTrkrConst = wimaxStateTrackerClass.getConstructor
654148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                        (new Class[] {Context.class, Handler.class});
655fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                wimaxStateTracker = (NetworkStateTracker) wmxStTrkrConst.newInstance(
656fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                        context, trackerHandler);
657148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
658148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                Constructor wmxSrvConst = wimaxServiceClass.getDeclaredConstructor
659148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                        (new Class[] {Context.class, wimaxStateTrackerClass});
660148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                wmxSrvConst.setAccessible(true);
661fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey                IBinder svcInvoker = (IBinder)wmxSrvConst.newInstance(context, wimaxStateTracker);
662148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                wmxSrvConst.setAccessible(false);
663148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
664148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                ServiceManager.addService(WimaxManagerConstants.WIMAX_SERVICE, svcInvoker);
665148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
666148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun            } catch(Exception ex) {
667148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                loge("Exception creating Wimax classes: " + ex.toString());
668148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun                return null;
669148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun            }
670148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        } else {
671148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun            loge("Wimax is not enabled or not added to the network attributes!!! ");
672148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun            return null;
673148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        }
674148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun
675148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun        return wimaxStateTracker;
676148c7d0de720a92632aa6ed10a39bfc38b427239tk.mun    }
6774c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
67986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * Sets the preferred network.
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param preference the new preference
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6828dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    public void setNetworkPreference(int preference) {
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
6848dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
6854c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        mHandler.sendMessage(
6864c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey                mHandler.obtainMessage(EVENT_SET_NETWORK_PREFERENCE, preference, 0));
6878dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
6888dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
6898dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    public int getNetworkPreference() {
6908dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        enforceAccessPermission();
6918dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        int preference;
6928dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        synchronized(this) {
6938dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            preference = mNetworkPreference;
6948dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
6958dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        return preference;
6968dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
6978dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
6988dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleSetNetworkPreference(int preference) {
69942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (ConnectivityManager.isNetworkTypeValid(preference) &&
700d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                mNetConfigs[preference] != null &&
701d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                mNetConfigs[preference].isDefault()) {
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mNetworkPreference != preference) {
7038dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                final ContentResolver cr = mContext.getContentResolver();
704bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                Settings.Global.putInt(cr, Settings.Global.NETWORK_PREFERENCE, preference);
7058dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                synchronized(this) {
7068dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    mNetworkPreference = preference;
7078dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enforcePreference();
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
713628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private int getConnectivityChangeDelay() {
714628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        final ContentResolver cr = mContext.getContentResolver();
715628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
716628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        /** Check system properties for the default value then use secure settings value, if any. */
717628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        int defaultDelay = SystemProperties.getInt(
718625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                "conn." + Settings.Global.CONNECTIVITY_CHANGE_DELAY,
719625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                ConnectivityManager.CONNECTIVITY_CHANGE_DELAY_DEFAULT);
720625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey        return Settings.Global.getInt(cr, Settings.Global.CONNECTIVITY_CHANGE_DELAY,
721628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                defaultDelay);
722628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
723628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int getPersistedNetworkPreference() {
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ContentResolver cr = mContext.getContentResolver();
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
727bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown        final int networkPrefSetting = Settings.Global
728bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                .getInt(cr, Settings.Global.NETWORK_PREFERENCE, -1);
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (networkPrefSetting != -1) {
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return networkPrefSetting;
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ConnectivityManager.DEFAULT_NETWORK_PREFERENCE;
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
73586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
73786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * Make the state of network connectivity conform to the preference settings
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * In this method, we only tear down a non-preferred network. Establishing
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a connection to the preferred network is taken care of when we handle
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the disconnect event from the non-preferred network
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (see {@link #handleDisconnect(NetworkInfo)}).
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enforcePreference() {
74442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (mNetTrackers[mNetworkPreference].getNetworkInfo().isConnected())
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
74742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (!mNetTrackers[mNetworkPreference].isAvailable())
74842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            return;
74942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
75042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        for (int t=0; t <= ConnectivityManager.MAX_RADIO_TYPE; t++) {
7515154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (t != mNetworkPreference && mNetTrackers[t] != null &&
75242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    mNetTrackers[t].getNetworkInfo().isConnected()) {
753ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt                if (DBG) {
754ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    log("tearing down " + mNetTrackers[t].getNetworkInfo() +
755ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt                            " in enforcePreference");
756ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt                }
75742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                teardown(mNetTrackers[t]);
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean teardown(NetworkStateTracker netTracker) {
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (netTracker.teardown()) {
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            netTracker.setTeardownRequested(true);
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
772fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * Check if UID should be blocked from using the network represented by the
773fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * given {@link NetworkStateTracker}.
774c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey     */
775fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private boolean isNetworkBlocked(NetworkStateTracker tracker, int uid) {
776fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        final String iface = tracker.getLinkProperties().getInterfaceName();
777fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
778fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        final boolean networkCostly;
779fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        final int uidRules;
780fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        synchronized (mRulesLock) {
781fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            networkCostly = mMeteredIfaces.contains(iface);
782fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
783fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        }
784d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
785fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        if (networkCostly && (uidRules & RULE_REJECT_METERED) != 0) {
786fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            return true;
787c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
788fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
789fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        // no restrictive rules; network is visible
790fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        return false;
791c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
792c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
793c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    /**
794fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * Return a filtered {@link NetworkInfo}, potentially marked
795fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * {@link DetailedState#BLOCKED} based on
796fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey     * {@link #isNetworkBlocked(NetworkStateTracker, int)}.
797c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey     */
798fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey    private NetworkInfo getFilteredNetworkInfo(NetworkStateTracker tracker, int uid) {
799fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        NetworkInfo info = tracker.getNetworkInfo();
800fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        if (isNetworkBlocked(tracker, uid)) {
801d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // network is blocked; clone and override state
802d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            info = new NetworkInfo(info);
803d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            info.setDetailedState(DetailedState.BLOCKED, null, null);
804c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
80569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        if (mLockdownTracker != null) {
80669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            info = mLockdownTracker.augmentNetworkInfo(info);
80769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
808d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        return info;
809c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
810c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
811c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    /**
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return NetworkInfo for the active (i.e., connected) network interface.
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * It is assumed that at most one network is active at a time. If more
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * than one is active, it is indeterminate which will be returned.
81586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * @return the info for the active network, or {@code null} if none is
81686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * active
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
818c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NetworkInfo getActiveNetworkInfo() {
820c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        enforceAccessPermission();
821c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final int uid = Binder.getCallingUid();
822c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return getNetworkInfo(mActiveDefaultNetwork, uid);
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
82569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    public NetworkInfo getActiveNetworkInfoUnfiltered() {
82669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        enforceAccessPermission();
82769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        if (isNetworkTypeValid(mActiveDefaultNetwork)) {
82869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[mActiveDefaultNetwork];
82969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            if (tracker != null) {
83069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                return tracker.getNetworkInfo();
83169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            }
83269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
83369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        return null;
83469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    }
83569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
836c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
837c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    public NetworkInfo getActiveNetworkInfoForUid(int uid) {
838c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        enforceConnectivityInternalPermission();
839c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return getNetworkInfo(mActiveDefaultNetwork, uid);
840c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
841c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
842c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NetworkInfo getNetworkInfo(int networkType) {
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceAccessPermission();
845c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final int uid = Binder.getCallingUid();
846c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return getNetworkInfo(networkType, uid);
847c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
848c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
849c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private NetworkInfo getNetworkInfo(int networkType, int uid) {
850c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        NetworkInfo info = null;
851c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        if (isNetworkTypeValid(networkType)) {
852c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[networkType];
853c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            if (tracker != null) {
854fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                info = getFilteredNetworkInfo(tracker, uid);
855c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
857c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return info;
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
860c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public NetworkInfo[] getAllNetworkInfo() {
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceAccessPermission();
863c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        final int uid = Binder.getCallingUid();
864d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final ArrayList<NetworkInfo> result = Lists.newArrayList();
865fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        synchronized (mRulesLock) {
866c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            for (NetworkStateTracker tracker : mNetTrackers) {
867c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                if (tracker != null) {
868fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                    result.add(getFilteredNetworkInfo(tracker, uid));
869c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                }
870c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
872d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        return result.toArray(new NetworkInfo[result.size()]);
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8759b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt    @Override
8769b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt    public boolean isNetworkSupported(int networkType) {
8779b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt        enforceAccessPermission();
8789b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt        return (isNetworkTypeValid(networkType) && (mNetTrackers[networkType] != null));
8799b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt    }
8809b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt
881d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    /**
882d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * Return LinkProperties for the active (i.e., connected) default
883d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * network interface.  It is assumed that at most one default network
884d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * is active at a time. If more than one is active, it is indeterminate
885d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * which will be returned.
886d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * @return the ip properties for the active network, or {@code null} if
887d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     * none is active
888d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt     */
889c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
890d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    public LinkProperties getActiveLinkProperties() {
891599115894f6f960a879d2e3036c547bbf4136020Robert Greenwalt        return getLinkProperties(mActiveDefaultNetwork);
892d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    }
893d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt
894c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    @Override
895d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    public LinkProperties getLinkProperties(int networkType) {
896d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt        enforceAccessPermission();
897c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        if (isNetworkTypeValid(networkType)) {
898c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[networkType];
899c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            if (tracker != null) {
900c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                return tracker.getLinkProperties();
901c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
902d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt        }
903d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt        return null;
904d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt    }
905d192dad69e9e5a820c5c11d8cd34460c9cc2ed11Robert Greenwalt
906d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    @Override
907d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    public NetworkState[] getAllNetworkState() {
908d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        enforceAccessPermission();
909d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final int uid = Binder.getCallingUid();
910d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final ArrayList<NetworkState> result = Lists.newArrayList();
911fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        synchronized (mRulesLock) {
912d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            for (NetworkStateTracker tracker : mNetTrackers) {
913d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                if (tracker != null) {
914fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                    final NetworkInfo info = getFilteredNetworkInfo(tracker, uid);
915d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                    result.add(new NetworkState(
916d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                            info, tracker.getLinkProperties(), tracker.getLinkCapabilities()));
917d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                }
918d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            }
919d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        }
920d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        return result.toArray(new NetworkState[result.size()]);
921d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    }
922d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
923f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    private NetworkState getNetworkStateUnchecked(int networkType) {
924f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        if (isNetworkTypeValid(networkType)) {
925f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[networkType];
926f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            if (tracker != null) {
927f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey                return new NetworkState(tracker.getNetworkInfo(), tracker.getLinkProperties(),
928f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey                        tracker.getLinkCapabilities());
929f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            }
930f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        }
931f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        return null;
932f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    }
933f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey
934f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    @Override
935f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
936f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        enforceAccessPermission();
93715ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey
93815ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey        final long token = Binder.clearCallingIdentity();
93915ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey        try {
94015ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey            final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
94115ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey            if (state != null) {
94215ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey                try {
94315ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey                    return mPolicyManager.getNetworkQuotaInfo(state);
94415ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey                } catch (RemoteException e) {
94515ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey                }
946f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey            }
94715ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey            return null;
94815ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey        } finally {
94915ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey            Binder.restoreCallingIdentity(token);
950f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey        }
951f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey    }
952f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey
9539f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey    @Override
9549f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey    public boolean isActiveNetworkMetered() {
9559f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey        enforceAccessPermission();
95615ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey        final long token = Binder.clearCallingIdentity();
95715ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey        try {
9585f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey            return isNetworkMeteredUnchecked(mActiveDefaultNetwork);
95915ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey        } finally {
96015ec7d6d7f23ec197a88619b5e03320cfebd2240Jeff Sharkey            Binder.restoreCallingIdentity(token);
9619f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey        }
9629f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey    }
9639f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey
9645f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey    private boolean isNetworkMeteredUnchecked(int networkType) {
9655f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey        final NetworkState state = getNetworkStateUnchecked(networkType);
9665f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey        if (state != null) {
9675f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey            try {
9685f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey                return mPolicyManager.isNetworkMetered(state);
9695f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey            } catch (RemoteException e) {
9705f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey            }
9715f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey        }
9725f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey        return false;
9735f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey    }
9745f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setRadios(boolean turnOn) {
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean result = true;
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (NetworkStateTracker t : mNetTrackers) {
9795154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (t != null) result = t.setRadio(turnOn) && result;
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setRadio(int netType, boolean turnOn) {
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ConnectivityManager.isNetworkTypeValid(netType)) {
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NetworkStateTracker tracker = mNetTrackers[netType];
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return tracker != null && tracker.setRadio(turnOn);
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
993216c181e76ee11a47a0b2a180f9af96740ab38adJeff Sharkey    private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
994216c181e76ee11a47a0b2a180f9af96740ab38adJeff Sharkey        @Override
995db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai        public void interfaceClassDataActivityChanged(String label, boolean active) {
996db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai            int deviceType = Integer.parseInt(label);
997db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai            sendDataActivityBroadcast(deviceType, active);
998db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai        }
999216c181e76ee11a47a0b2a180f9af96740ab38adJeff Sharkey    };
1000db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai
10019c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    /**
10029c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     * Used to notice when the calling process dies so we can self-expire
10039c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     *
10049c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     * Also used to know if the process has cleaned up after itself when
10059c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     * our auto-expire timer goes off.  The timer has a link to an object.
10069c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     *
10079c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt     */
100842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private class FeatureUser implements IBinder.DeathRecipient {
100942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int mNetworkType;
101042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String mFeature;
101142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        IBinder mBinder;
101242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int mPid;
101342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int mUid;
1014b928535902b204ac3ec25f161352786842248767Robert Greenwalt        long mCreateTime;
101542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
101642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        FeatureUser(int type, String feature, IBinder binder) {
101742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            super();
101842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mNetworkType = type;
101942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mFeature = feature;
102042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mBinder = binder;
102142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mPid = getCallingPid();
102242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mUid = getCallingUid();
1023b928535902b204ac3ec25f161352786842248767Robert Greenwalt            mCreateTime = System.currentTimeMillis();
10249c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
102542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            try {
102642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                mBinder.linkToDeath(this, 0);
102742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } catch (RemoteException e) {
102842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                binderDied();
102942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
103042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
103142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
103242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        void unlinkDeathRecipient() {
103342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mBinder.unlinkToDeath(this, 0);
103442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
103542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
103642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        public void binderDied() {
1037ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            log("ConnectivityService FeatureUser binderDied(" +
1038b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    mNetworkType + ", " + mFeature + ", " + mBinder + "), created " +
1039b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    (System.currentTimeMillis() - mCreateTime) + " mSec ago");
10409c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            stopUsingNetworkFeature(this, false);
104142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
104242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
10439c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        public void expire() {
104458d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) {
104558d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                log("ConnectivityService FeatureUser expire(" +
104658d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                        mNetworkType + ", " + mFeature + ", " + mBinder +"), created " +
104758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                        (System.currentTimeMillis() - mCreateTime) + " mSec ago");
104858d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            }
10499c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            stopUsingNetworkFeature(this, false);
10509c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
1051b928535902b204ac3ec25f161352786842248767Robert Greenwalt
10523bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        public boolean isSameUser(FeatureUser u) {
10533bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            if (u == null) return false;
10543bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
10553bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            return isSameUser(u.mPid, u.mUid, u.mNetworkType, u.mFeature);
10563bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        }
10573bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
10583bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        public boolean isSameUser(int pid, int uid, int networkType, String feature) {
10593bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            if ((mPid == pid) && (mUid == uid) && (mNetworkType == networkType) &&
10603bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                TextUtils.equals(mFeature, feature)) {
10613bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                return true;
10623bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            }
10633bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            return false;
10643bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo        }
10653bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
1066b928535902b204ac3ec25f161352786842248767Robert Greenwalt        public String toString() {
1067b928535902b204ac3ec25f161352786842248767Robert Greenwalt            return "FeatureUser("+mNetworkType+","+mFeature+","+mPid+","+mUid+"), created " +
1068b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    (System.currentTimeMillis() - mCreateTime) + " mSec ago";
1069b928535902b204ac3ec25f161352786842248767Robert Greenwalt        }
107042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
107142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
10729c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    // javadoc from interface
107342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    public int startUsingNetworkFeature(int networkType, String feature,
107442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            IBinder binder) {
10755a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt        long startTime = 0;
10765a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt        if (DBG) {
10775a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            startTime = SystemClock.elapsedRealtime();
10785a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt        }
1079c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville        if (VDBG) {
10805f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey            log("startUsingNetworkFeature for net " + networkType + ": " + feature + ", uid="
10815f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey                    + Binder.getCallingUid());
108242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
10845a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt        try {
10855a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
10865a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    mNetConfigs[networkType] == null) {
1087a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                return PhoneConstants.APN_REQUEST_FAILED;
10885a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            }
108942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
10905a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            FeatureUser f = new FeatureUser(networkType, feature, binder);
109142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
10925a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            // TODO - move this into individual networktrackers
10935a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
109450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
109569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            if (mLockdownEnabled) {
109669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                // Since carrier APNs usually aren't available from VPN
109769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                // endpoint, mark them as unavailable.
109869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
109969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            }
110069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
11015a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            if (mProtectedNetworks.contains(usedNetworkType)) {
11025a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                enforceConnectivityInternalPermission();
11035a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            }
110450393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
11055a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            // if UID is restricted, don't allow them to bring up metered APNs
11065a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            final boolean networkMetered = isNetworkMeteredUnchecked(usedNetworkType);
11075a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            final int uidRules;
11085a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            synchronized (mRulesLock) {
11095a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                uidRules = mUidRules.get(Binder.getCallingUid(), RULE_ALLOW_ALL);
11105a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            }
11115a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            if (networkMetered && (uidRules & RULE_REJECT_METERED) != 0) {
1112a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                return PhoneConstants.APN_REQUEST_FAILED;
11135a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            }
11145f4dafb48e065d07f01ee83a6b54aa4bd4b25fc4Jeff Sharkey
11155a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            NetworkStateTracker network = mNetTrackers[usedNetworkType];
11165a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            if (network != null) {
11175a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                Integer currentPid = new Integer(getCallingPid());
11185a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                if (usedNetworkType != networkType) {
11195a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    NetworkInfo ni = network.getNetworkInfo();
11205a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt
11215a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    if (ni.isAvailable() == false) {
11225a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
11235a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            if (DBG) log("special network not available ni=" + ni.getTypeName());
1124a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
11255a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        } else {
11265a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            // else make the attempt anyway - probably giving REQUEST_STARTED below
11275a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            if (DBG) {
11285a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                log("special network not available, but try anyway ni=" +
11295a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                        ni.getTypeName());
11305a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            }
1131c7d7eafb66f14766e9fa0013407862502dcdfb66Wink Saville                        }
1132e32e812b11520b244374371ee49eaed20c84a6e3Robert Greenwalt                    }
11333bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
11345a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    int restoreTimer = getRestoreDefaultNetworkDelay(usedNetworkType);
11355a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt
11365a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    synchronized(this) {
11375a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        boolean addToList = true;
11385a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        if (restoreTimer < 0) {
11395a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            // In case there is no timer is specified for the feature,
11405a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            // make sure we don't add duplicate entry with the same request.
11415a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            for (FeatureUser u : mFeatureUsers) {
11425a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                if (u.isSameUser(f)) {
11435a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                    // Duplicate user is found. Do not add.
11445a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                    addToList = false;
11455a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                    break;
11465a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                }
11473bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                            }
11483bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                        }
11493bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo
11505a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        if (addToList) mFeatureUsers.add(f);
11515a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
11525a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            // this gets used for per-pid dns when connected
11535a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            mNetRequestersPids[usedNetworkType].add(currentPid);
11545a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        }
11559c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    }
11569c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
11575a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    if (restoreTimer >= 0) {
11585a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        mHandler.sendMessageDelayed(mHandler.obtainMessage(
11595a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                EVENT_RESTORE_DEFAULT_NETWORK, f), restoreTimer);
11605a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    }
116142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
11625a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    if ((ni.isConnectedOrConnecting() == true) &&
11635a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            !network.isTeardownRequested()) {
11645a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        if (ni.isConnected() == true) {
11655a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            final long token = Binder.clearCallingIdentity();
11665a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            try {
11675a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                // add the pid-specific dns
11685a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                handleDnsConfigurationChange(usedNetworkType);
11695a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                if (VDBG) log("special network already active");
11705a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            } finally {
11715a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                Binder.restoreCallingIdentity(token);
11725a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            }
1173a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                            return PhoneConstants.APN_ALREADY_ACTIVE;
11748beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt                        }
11755a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        if (VDBG) log("special network already connecting");
1176a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                        return PhoneConstants.APN_REQUEST_STARTED;
117742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
117842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
11795a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    // check if the radio in play can make another contact
11805a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    // assume if cannot for now
118142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
11825a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    if (DBG) {
11835a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        log("startUsingNetworkFeature reconnecting to " + networkType + ": " +
11845a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                                feature);
11855a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    }
11865a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    network.reconnect();
1187a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                    return PhoneConstants.APN_REQUEST_STARTED;
11885a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                } else {
11895a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    // need to remember this unsupported request so we respond appropriately on stop
11905a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    synchronized(this) {
11915a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        mFeatureUsers.add(f);
11925a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
11935a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            // this gets used for per-pid dns when connected
11945a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                            mNetRequestersPids[usedNetworkType].add(currentPid);
11955a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                        }
11960be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                    }
11975a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    return -1;
11980be1e9844a16d7d7708fdb446b330533cd1d3260Robert Greenwalt                }
119942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
1200a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
12015a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt         } finally {
12025a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            if (DBG) {
12035a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                final long execTime = SystemClock.elapsedRealtime() - startTime;
12045a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                if (execTime > 250) {
12055a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    loge("startUsingNetworkFeature took too long: " + execTime + "ms");
12065a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                } else {
12075a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                    if (VDBG) log("startUsingNetworkFeature took " + execTime + "ms");
12085a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt                }
12095a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt            }
12105a0c320a820a0ccaafaa87ad858a29bf5d88a8b9Robert Greenwalt         }
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12139c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    // javadoc from interface
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int stopUsingNetworkFeature(int networkType, String feature) {
1215b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt        enforceChangePermission();
1216b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt
12179c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int pid = getCallingPid();
12189c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int uid = getCallingUid();
12199c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
12209c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        FeatureUser u = null;
12219c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        boolean found = false;
12229c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
12239c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        synchronized(this) {
12243bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo            for (FeatureUser x : mFeatureUsers) {
12253bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                if (x.isSameUser(pid, uid, networkType, feature)) {
12263bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    u = x;
12279c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    found = true;
12289c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    break;
12299c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                }
12309c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            }
12319c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
12329c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        if (found && u != null) {
12339c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // stop regardless of how many other time this proc had called start
12349c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            return stopUsingNetworkFeature(u, true);
12359c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        } else {
12369c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // none found!
1237c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (VDBG) log("stopUsingNetworkFeature - not a live request, ignoring");
12389c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            return 1;
12399c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
124042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
124142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
12429c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt    private int stopUsingNetworkFeature(FeatureUser u, boolean ignoreDups) {
12439c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int networkType = u.mNetworkType;
12449c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        String feature = u.mFeature;
12459c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int pid = u.mPid;
12469c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        int uid = u.mUid;
12479c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
12489c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        NetworkStateTracker tracker = null;
12499c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        boolean callTeardown = false;  // used to carry our decision outside of sync block
12509c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt
1251c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville        if (VDBG) {
1252c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            log("stopUsingNetworkFeature: net " + networkType + ": " + feature);
125342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
1254b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
1256c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (DBG) {
1257c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
1258c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                        ", net is invalid");
1259c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            }
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
126242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
12639c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        // need to link the mFeatureUsers list with the mNetRequestersPids state in this
12649c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        // sync block
12659c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        synchronized(this) {
12669c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // check if this process still has an outstanding start request
12679c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            if (!mFeatureUsers.contains(u)) {
1268c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                if (VDBG) {
1269c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    log("stopUsingNetworkFeature: this process has no outstanding requests" +
1270c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                        ", ignoring");
1271c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                }
12729c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                return 1;
12739c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            }
12749c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            u.unlinkDeathRecipient();
12759c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            mFeatureUsers.remove(mFeatureUsers.indexOf(u));
12769c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // If we care about duplicate requests, check for that here.
12779c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            //
12789c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // This is done to support the extension of a request - the app
12799c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // can request we start the network feature again and renew the
12809c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // auto-shutoff delay.  Normal "stop" calls from the app though
12819c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // do not pay attention to duplicate requests - in effect the
12829c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            // API does not refcount and a single stop will counter multiple starts.
12839c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            if (ignoreDups == false) {
12843bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                for (FeatureUser x : mFeatureUsers) {
12853bed4c9f50b3601e2ceec249e2ee83f39192f5dbKazuhiro Ondo                    if (x.isSameUser(u)) {
1286c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                        if (VDBG) log("stopUsingNetworkFeature: dup is found, ignoring");
12879c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                        return 1;
12889c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    }
128942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
129042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
129142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1292aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            // TODO - move to individual network trackers
1293aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
1294aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
12959c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt            tracker =  mNetTrackers[usedNetworkType];
12965154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (tracker == null) {
1297c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                if (DBG) {
1298c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
1299c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                            " no known tracker for used net type " + usedNetworkType);
1300c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                }
13015154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                return -1;
13025154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            }
13035154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt            if (usedNetworkType != networkType) {
13049c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                Integer currentPid = new Integer(pid);
13059c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                mNetRequestersPids[usedNetworkType].remove(currentPid);
1306421c72b6773582dd1473ace44c42d4e0ee1287e3Robert Greenwalt                reassessPidDns(pid, true);
13079c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                if (mNetRequestersPids[usedNetworkType].size() != 0) {
1308c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    if (VDBG) {
1309c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                        log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
1310c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                                " others still using it");
1311c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    }
13129c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    return 1;
13139c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                }
13149c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                callTeardown = true;
131519b9ab46a9faee6031aaf6c78748401943fea117Robert Greenwalt            } else {
1316c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                if (DBG) {
1317c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
1318c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                            " not a known feature - dropping");
1319c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                }
132042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
13219c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        }
1322c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville
13239c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt        if (callTeardown) {
1324c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (DBG) {
1325c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                log("stopUsingNetworkFeature: teardown net " + networkType + ": " + feature);
1326c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            }
132742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            tracker.teardown();
132842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            return 1;
132942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        } else {
133002648a4b8422733ed401f07edf8e426318bb2f8dRobert Greenwalt            return -1;
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1335585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @deprecated use requestRouteToHostAddress instead
1336585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     *
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ensure that a network route exists to deliver traffic to the specified
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * host via the specified network interface.
133986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * @param networkType the type of the network over which traffic to the
134086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * specified host is to be routed
134186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * @param hostAddress the IP address of the host to which the route is
134286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * desired
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return {@code true} on success, {@code false} on failure
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean requestRouteToHost(int networkType, int hostAddress) {
1346585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
1347585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
1348585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        if (inetAddress == null) {
1349585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            return false;
1350585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        }
1351585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
1352585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt        return requestRouteToHostAddress(networkType, inetAddress.getAddress());
1353585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    }
1354585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt
1355585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    /**
1356585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * Ensure that a network route exists to deliver traffic to the specified
1357585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * host via the specified network interface.
1358585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param networkType the type of the network over which traffic to the
1359585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * specified host is to be routed
1360585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @param hostAddress the IP address of the host to which the route is
1361585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * desired
1362585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     * @return {@code true} on success, {@code false} on failure
1363585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt     */
1364585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt    public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enforceChangePermission();
136650393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        if (mProtectedNetworks.contains(networkType)) {
136750393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt            enforceConnectivityInternalPermission();
136850393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        }
136950393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
13718beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt            if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        NetworkStateTracker tracker = mNetTrackers[networkType];
1375da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        DetailedState netState = tracker.getNetworkInfo().getDetailedState();
13768206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt
1377da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        if (tracker == null || (netState != DetailedState.CONNECTED &&
1378da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                netState != DetailedState.CAPTIVE_PORTAL_CHECK) ||
13795154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                tracker.isTeardownRequested()) {
138058d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) {
1381ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                log("requestRouteToHostAddress on down network " +
1382585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt                           "(" + networkType + ") - dropped");
13838206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt            }
13848206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt            return false;
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13868beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt        final long token = Binder.clearCallingIdentity();
138747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        try {
1388585ac0fc8dde3fe35ec4c71c8f215f2c84139b8bRobert Greenwalt            InetAddress addr = InetAddress.getByAddress(hostAddress);
13890a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            LinkProperties lp = tracker.getLinkProperties();
1390ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            return addRouteToAddress(lp, addr);
13918beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt        } catch (UnknownHostException e) {
13928beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt            if (DBG) log("requestRouteToHostAddress got " + e.toString());
13938beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt        } finally {
13948beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt            Binder.restoreCallingIdentity(token);
13958beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt        }
139647f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        return false;
1397d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
1398d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
13993b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt    private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
14003b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt        return modifyRoute(p.getInterfaceName(), p, r, 0, ADD, toDefaultTable);
14010a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
1402d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
14033b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt    private boolean removeRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
14043b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt        return modifyRoute(p.getInterfaceName(), p, r, 0, REMOVE, toDefaultTable);
14050a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    }
14060a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
1407ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
14083b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt        return modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE);
1409ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    }
1410ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt
1411ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
14123b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt        return modifyRouteToAddress(lp, addr, REMOVE, TO_DEFAULT_TABLE);
1413ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    }
1414ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt
14153b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt    private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd,
14163b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            boolean toDefaultTable) {
1417ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr);
1418ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        if (bestRoute == null) {
1419ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            bestRoute = RouteInfo.makeHostRoute(addr);
1420ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        } else {
1421ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (bestRoute.getGateway().equals(addr)) {
1422ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // if there is no better route, add the implied hostroute for our gateway
1423ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                bestRoute = RouteInfo.makeHostRoute(addr);
1424ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            } else {
1425ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // if we will connect to this through another route, add a direct route
1426ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // to it's gateway
1427ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway());
1428ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            }
1429ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        }
14303b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt        return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd, toDefaultTable);
1431ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt    }
1432ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt
14330a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
14343b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            boolean doAdd, boolean toDefaultTable) {
14358beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt        if ((ifaceName == null) || (lp == null) || (r == null)) {
14368beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt            if (DBG) log("modifyRoute got unexpected null: " + ifaceName + ", " + lp + ", " + r);
14378beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt            return false;
14388beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt        }
14390a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
14400a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
14413b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            loge("Error modifying route - too much recursion");
1442d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            return false;
1443d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
1444f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt
14450a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (r.isHostRoute() == false) {
14460a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), r.getGateway());
14470a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (bestRoute != null) {
1448476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                if (bestRoute.getGateway().equals(r.getGateway())) {
1449476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    // if there is no better route, add the implied hostroute for our gateway
14500a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    bestRoute = RouteInfo.makeHostRoute(r.getGateway());
1451476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                } else {
1452476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    // if we will connect to our gateway through another route, add a direct
1453476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    // route to it's gateway
1454476f55253adc670d7290ad8c90b5adc9e4f58d3bRobert Greenwalt                    bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
14550a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
14563b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd, toDefaultTable);
14570a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
1458f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
14590a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (doAdd) {
146058d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) log("Adding " + r + " for interface " + ifaceName);
14610a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            try {
14623b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                if (toDefaultTable) {
14633b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                    mAddedRoutes.add(r);  // only track default table - only one apps can effect
14643b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                    mNetd.addRoute(ifaceName, r);
14653b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                } else {
14663b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                    mNetd.addSecondaryRoute(ifaceName, r);
14673b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                }
14680a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            } catch (Exception e) {
14690a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                // never crash - catch them all
14708beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt                if (DBG) loge("Exception trying to add a route: " + e);
1471f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt                return false;
1472f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt            }
14730a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        } else {
14740a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // if we remove this one and there are no more like it, then refcount==0 and
14750a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // we can remove it from the table
14763b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            if (toDefaultTable) {
14773b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                mAddedRoutes.remove(r);
14783b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                if (mAddedRoutes.contains(r) == false) {
14793b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                    if (VDBG) log("Removing " + r + " for interface " + ifaceName);
14803b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                    try {
14813b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                        mNetd.removeRoute(ifaceName, r);
14823b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                    } catch (Exception e) {
14833b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                        // never crash - catch them all
14842473a4bae16b2713753dd80f8356ad18fce43207Robert Greenwalt                        if (VDBG) loge("Exception trying to remove a route: " + e);
14853b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                        return false;
14863b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                    }
14873b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                } else {
14883b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                    if (VDBG) log("not removing " + r + " as it's still in use");
14893b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                }
14903b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            } else {
149158d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                if (VDBG) log("Removing " + r + " for interface " + ifaceName);
14920a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                try {
14933b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                    mNetd.removeSecondaryRoute(ifaceName, r);
14940a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                } catch (Exception e) {
14950a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    // never crash - catch them all
14962473a4bae16b2713753dd80f8356ad18fce43207Robert Greenwalt                    if (VDBG) loge("Exception trying to remove a route: " + e);
14970a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    return false;
14980a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                }
14990a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            }
1500f43396caaaae8f336bcf6fe9128a89dc7a7b0a5cRobert Greenwalt        }
15010a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        return true;
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1505c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     * @see ConnectivityManager#getMobileDataEnabled()
1506c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     */
1507c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    public boolean getMobileDataEnabled() {
1508e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        // TODO: This detail should probably be in DataConnectionTracker's
1509e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        //       which is where we store the value and maybe make this
1510e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        //       asynchronous.
1511c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        enforceAccessPermission();
1512bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey        boolean retVal = Settings.Global.getInt(mContext.getContentResolver(),
1513bdfce2ec05a3e9ca6acd6711de6133e06f2446e6Jeff Sharkey                Settings.Global.MOBILE_DATA, 1) == 1;
151458d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (VDBG) log("getMobileDataEnabled returning " + retVal);
1515c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        return retVal;
1516c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    }
1517c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt
1518d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    public void setDataDependency(int networkType, boolean met) {
151950393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt        enforceConnectivityInternalPermission();
152050393202f3ae0ab9114075ecc5b4c92faaf96251Robert Greenwalt
1521d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_DEPENDENCY_MET,
1522d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                (met ? ENABLED : DISABLED), networkType));
1523d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    }
1524d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt
1525d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    private void handleSetDependencyMet(int networkType, boolean met) {
1526d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetTrackers[networkType] != null) {
1527d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (DBG) {
1528d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                log("handleSetDependencyMet(" + networkType + ", " + met + ")");
1529d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            }
1530d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            mNetTrackers[networkType].setDependencyMet(met);
1531d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        }
1532d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt    }
1533d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt
1534c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
1535c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        @Override
1536fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        public void onUidRulesChanged(int uid, int uidRules) {
15371f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            // caller is NPMS, since we only register with them
1538c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            if (LOGD_RULES) {
153958d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
1540c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
1541c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1542fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            synchronized (mRulesLock) {
1543c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                // skip update when we've already applied rules
1544c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                final int oldRules = mUidRules.get(uid, RULE_ALLOW_ALL);
1545c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                if (oldRules == uidRules) return;
1546c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1547c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey                mUidRules.put(uid, uidRules);
1548c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            }
1549c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1550c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            // TODO: notify UID when it has requested targeted updates
1551c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
1552fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
1553fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        @Override
1554fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        public void onMeteredIfacesChanged(String[] meteredIfaces) {
15551f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            // caller is NPMS, since we only register with them
1556fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            if (LOGD_RULES) {
155758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
1558fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            }
1559fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey
1560fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            synchronized (mRulesLock) {
1561fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                mMeteredIfaces.clear();
1562fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                for (String iface : meteredIfaces) {
1563fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                    mMeteredIfaces.add(iface);
1564fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey                }
1565fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey            }
1566fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey        }
15671f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey
15681f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey        @Override
15691f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey        public void onRestrictBackgroundChanged(boolean restrictBackground) {
15701f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            // caller is NPMS, since we only register with them
15711f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            if (LOGD_RULES) {
15721f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey                log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
15731f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            }
15741f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey
15751f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            // kick off connectivity change broadcast for active network, since
15761f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            // global background policy change is radical.
15771f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            final int networkType = mActiveDefaultNetwork;
15781f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            if (isNetworkTypeValid(networkType)) {
15791f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey                final NetworkStateTracker tracker = mNetTrackers[networkType];
15801f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey                if (tracker != null) {
15811f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey                    final NetworkInfo info = tracker.getNetworkInfo();
15821f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey                    if (info != null && info.isConnected()) {
15831f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey                        sendConnectedBroadcast(info);
15841f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey                    }
15851f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey                }
15861f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey            }
15871f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey        }
1588c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    };
1589c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
1590c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt    /**
1591c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     * @see ConnectivityManager#setMobileDataEnabled(boolean)
1592c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt     */
15938dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    public void setMobileDataEnabled(boolean enabled) {
1594c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt        enforceChangePermission();
1595ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        if (DBG) log("setMobileDataEnabled(" + enabled + ")");
1596c03fa5014912684367174ff3cce664deb29f5e0eRobert Greenwalt
15978dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA,
1598d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                (enabled ? ENABLED : DISABLED), 0));
15998dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
16008dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
16018dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleSetMobileData(boolean enabled) {
1602e798268f16ec6d0542616ea45ca0bb18ae2645eeWink Saville        if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {
160358d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) {
160458d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                log(mNetTrackers[ConnectivityManager.TYPE_MOBILE].toString() + enabled);
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
16068e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            mNetTrackers[ConnectivityManager.TYPE_MOBILE].setUserDataEnable(enabled);
16078e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        }
1608b97d34c7c81ed7def6d0c1d7a76d057051f7d154tk.mun        if (mNetTrackers[ConnectivityManager.TYPE_WIMAX] != null) {
1609b97d34c7c81ed7def6d0c1d7a76d057051f7d154tk.mun            if (VDBG) {
1610b97d34c7c81ed7def6d0c1d7a76d057051f7d154tk.mun                log(mNetTrackers[ConnectivityManager.TYPE_WIMAX].toString() + enabled);
1611b97d34c7c81ed7def6d0c1d7a76d057051f7d154tk.mun            }
1612b97d34c7c81ed7def6d0c1d7a76d057051f7d154tk.mun            mNetTrackers[ConnectivityManager.TYPE_WIMAX].setUserDataEnable(enabled);
1613b97d34c7c81ed7def6d0c1d7a76d057051f7d154tk.mun        }
16148e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
16158e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
16168e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    @Override
16178e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    public void setPolicyDataEnable(int networkType, boolean enabled) {
16188e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        // only someone like NPMS should only be calling us
16198e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
16208e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
16218e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mHandler.sendMessage(mHandler.obtainMessage(
16228e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                EVENT_SET_POLICY_DATA_ENABLE, networkType, (enabled ? ENABLED : DISABLED)));
16238e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
16248e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
16258e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private void handleSetPolicyDataEnable(int networkType, boolean enabled) {
16268e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        if (isNetworkTypeValid(networkType)) {
16278e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            final NetworkStateTracker tracker = mNetTrackers[networkType];
16288e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            if (tracker != null) {
16298e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                tracker.setPolicyDataEnable(enabled);
16308e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey            }
16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enforceAccessPermission() {
163586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt        mContext.enforceCallingOrSelfPermission(
163686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                android.Manifest.permission.ACCESS_NETWORK_STATE,
163786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                "ConnectivityService");
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enforceChangePermission() {
164186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt        mContext.enforceCallingOrSelfPermission(
164286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                android.Manifest.permission.CHANGE_NETWORK_STATE,
164386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                "ConnectivityService");
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1646d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // TODO Make this a special check when it goes public
1647d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    private void enforceTetherChangePermission() {
1648d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        mContext.enforceCallingOrSelfPermission(
1649d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt                android.Manifest.permission.CHANGE_NETWORK_STATE,
1650d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt                "ConnectivityService");
1651d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
1652d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
16532a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    private void enforceTetherAccessPermission() {
16542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        mContext.enforceCallingOrSelfPermission(
16552a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt                android.Manifest.permission.ACCESS_NETWORK_STATE,
16562a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt                "ConnectivityService");
16572a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
16582a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
165914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    private void enforceConnectivityInternalPermission() {
166014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mContext.enforceCallingOrSelfPermission(
166114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                android.Manifest.permission.CONNECTIVITY_INTERNAL,
166214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                "ConnectivityService");
166314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    }
166414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
166686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * Handle a {@code DISCONNECTED} event. If this pertains to the non-active
166786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * network, we ignore it. If it is for the active network, we send out a
166886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * broadcast. But first, we check whether it might be possible to connect
166986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt     * to a different network.
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info the {@code NetworkInfo} for the network
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleDisconnect(NetworkInfo info) {
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
167442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int prevNetType = info.getType();
16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
167642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        mNetTrackers[prevNetType].setTeardownRequested(false);
16770412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
16780412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        // Remove idletimer previously setup in {@code handleConnect}
16790412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        removeDataActivityTracking(prevNetType);
16800412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * If the disconnected network is not the active one, then don't report
16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * this as a loss of connectivity. What probably happened is that we're
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * getting the disconnect for a network that we explicitly disabled
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * in accordance with network preference policies.
16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1687d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (!mNetConfigs[prevNetType].isDefault()) {
168842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            List pids = mNetRequestersPids[prevNetType];
168942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            for (int i = 0; i<pids.size(); i++) {
169042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                Integer pid = (Integer)pids.get(i);
169142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // will remove them because the net's no longer connected
169242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // need to do this now as only now do we know the pids and
169342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                // can properly null things that are no longer referenced.
169442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                reassessPidDns(pid.intValue(), false);
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
16999538bdd3c77968c7673719c580ae653ede4654d6Irfan Sheriff        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
170075fbb4bdfde9188081f000506845d852f31362f0Jeff Sharkey        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.isFailover()) {
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            info.setFailover(false);
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getReason() != null) {
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getExtraInfo() != null) {
170986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
171086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    info.getExtraInfo());
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
171242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1713d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[prevNetType].isDefault()) {
1714f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            tryFailover(prevNetType);
1715f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            if (mActiveDefaultNetwork != -1) {
1716f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
1717cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
1718cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            } else {
1719029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt                mDefaultInetConditionPublished = 0; // we're not connected anymore
1720cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
1721cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            }
1722da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
1723029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
1724ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt
1725ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        // Reset interface if no other connections are using the same interface
1726ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        boolean doReset = true;
1727ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        LinkProperties linkProperties = mNetTrackers[prevNetType].getLinkProperties();
1728ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        if (linkProperties != null) {
1729ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            String oldIface = linkProperties.getInterfaceName();
1730ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            if (TextUtils.isEmpty(oldIface) == false) {
1731ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                for (NetworkStateTracker networkStateTracker : mNetTrackers) {
1732ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    if (networkStateTracker == null) continue;
1733ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    NetworkInfo networkInfo = networkStateTracker.getNetworkInfo();
1734ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    if (networkInfo.isConnected() && networkInfo.getType() != prevNetType) {
1735ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        LinkProperties l = networkStateTracker.getLinkProperties();
1736ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        if (l == null) continue;
1737ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        if (oldIface.equals(l.getInterfaceName())) {
1738ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                            doReset = false;
1739ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                            break;
1740ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                        }
1741ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                    }
1742ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                }
1743ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            }
1744ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        }
1745ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt
1746da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        // do this before we broadcast the change
1747ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        handleConnectivityChange(prevNetType, doReset);
1748da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt
1749961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        final Intent immediateIntent = new Intent(intent);
1750961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
1751961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        sendStickyBroadcast(immediateIntent);
1752628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
1753da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        /*
1754da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * If the failover network is already connected, then immediately send
1755da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * out a followup broadcast indicating successful failover
1756da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         */
1757f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt        if (mActiveDefaultNetwork != -1) {
1758628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            sendConnectedBroadcastDelayed(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo(),
1759628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    getConnectivityChangeDelay());
1760da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
1761da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt    }
1762da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt
1763f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt    private void tryFailover(int prevNetType) {
176442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        /*
1765bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt         * If this is a default network, check if other defaults are available.
1766bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt         * Try to reconnect on all available and let them hash it out when
1767bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt         * more than one connects.
176842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         */
1769d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[prevNetType].isDefault()) {
177042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (mActiveDefaultNetwork == prevNetType) {
177142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                mActiveDefaultNetwork = -1;
177242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
177342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1774f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            // don't signal a reconnect for anything lower or equal priority than our
1775f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            // current connected default
1776f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            // TODO - don't filter by priority now - nice optimization but risky
1777f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt//            int currentPriority = -1;
1778f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt//            if (mActiveDefaultNetwork != -1) {
1779d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt//                currentPriority = mNetConfigs[mActiveDefaultNetwork].mPriority;
1780f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt//            }
1781da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt            for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
17825154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt                if (checkType == prevNetType) continue;
1783d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                if (mNetConfigs[checkType] == null) continue;
1784d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                if (!mNetConfigs[checkType].isDefault()) continue;
1785424781e2e1a1f1447eea733ffd1dc0f8006b628eRobert Greenwalt                if (mNetTrackers[checkType] == null) continue;
17869f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville
17879f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// Enabling the isAvailable() optimization caused mobile to not get
17889f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// selected if it was in the middle of error handling. Specifically
17899f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// a moble connection that took 30 seconds to complete the DEACTIVATE_DATA_CALL
17909f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// would not be available and we wouldn't get connected to anything.
17919f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// So removing the isAvailable() optimization below for now. TODO: This
17929f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// optimization should work and we need to investigate why it doesn't work.
17939f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// This could be related to how DEACTIVATE_DATA_CALL is reporting its
17949f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville// complete before it is really complete.
17959f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville//                if (!mNetTrackers[checkType].isAvailable()) continue;
17969f7a0b2b0270b1ad59d2103839b1d4b02f910a90Wink Saville
1797d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt//                if (currentPriority >= mNetConfigs[checkType].mPriority) continue;
1798bff9018b74e68fe9bceb87ee2b7c2549f04e13c2Robert Greenwalt
1799f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkStateTracker checkTracker = mNetTrackers[checkType];
1800f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkInfo checkInfo = checkTracker.getNetworkInfo();
1801f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                if (!checkInfo.isConnectedOrConnecting() || checkTracker.isTeardownRequested()) {
1802f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                    checkInfo.setFailover(true);
1803f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                    checkTracker.reconnect();
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1805f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                if (DBG) log("Attempting to switch to " + checkInfo.getTypeName());
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
181069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    public void sendConnectedBroadcast(NetworkInfo info) {
1811961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        sendGeneralBroadcast(info, CONNECTIVITY_ACTION_IMMEDIATE);
1812961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
18131e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    }
18141e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt
1815628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private void sendConnectedBroadcastDelayed(NetworkInfo info, int delayMs) {
1816961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        sendGeneralBroadcast(info, CONNECTIVITY_ACTION_IMMEDIATE);
1817961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        sendGeneralBroadcastDelayed(info, CONNECTIVITY_ACTION, delayMs);
1818628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
1819628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
18201e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    private void sendInetConditionBroadcast(NetworkInfo info) {
18211e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt        sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
18221e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt    }
18231e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt
1824628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
182569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        if (mLockdownTracker != null) {
182669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            info = mLockdownTracker.augmentNetworkInfo(info);
182769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
182869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
18291e9aac2bd855f12708d3049eff4435fa4a2f4317Robert Greenwalt        Intent intent = new Intent(bcastType);
18309538bdd3c77968c7673719c580ae653ede4654d6Irfan Sheriff        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
183175fbb4bdfde9188081f000506845d852f31362f0Jeff Sharkey        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.isFailover()) {
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            info.setFailover(false);
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getReason() != null) {
18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info.getExtraInfo() != null) {
184086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
184186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    info.getExtraInfo());
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1843d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
1844628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        return intent;
1845628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
1846628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
1847628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
1848628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        sendStickyBroadcast(makeGeneralIntent(info, bcastType));
1849628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
1850628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
1851628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private void sendGeneralBroadcastDelayed(NetworkInfo info, String bcastType, int delayMs) {
1852628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        sendStickyBroadcastDelayed(makeGeneralIntent(info, bcastType), delayMs);
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1855db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai    private void sendDataActivityBroadcast(int deviceType, boolean active) {
1856db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai        Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
1857db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai        intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
1858db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai        intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
1859fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        final long ident = Binder.clearCallingIdentity();
1860fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        try {
1861fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
1862fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn                    RECEIVE_DATA_ACTIVITY_CHANGE, null, null, 0, null, null);
1863fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        } finally {
1864fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            Binder.restoreCallingIdentity(ident);
1865fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        }
1866db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai    }
1867db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when an attempt to fail over to another network has failed.
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info the {@link NetworkInfo} for the failed network
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleConnectionFailure(NetworkInfo info) {
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNetTrackers[info.getType()].setTeardownRequested(false);
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
187542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String reason = info.getReason();
187642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String extraInfo = info.getExtraInfo();
187742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
1878572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt        String reasonText;
1879572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt        if (reason == null) {
1880572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt            reasonText = ".";
1881572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt        } else {
1882572172befbdf020e96ee4b10506b2b7cd5f1a09bRobert Greenwalt            reasonText = " (" + reason + ").";
188342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
1884ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        loge("Attempt to connect to " + info.getTypeName() + " failed" + reasonText);
188586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
188642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
18879538bdd3c77968c7673719c580ae653ede4654d6Irfan Sheriff        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
188875fbb4bdfde9188081f000506845d852f31362f0Jeff Sharkey        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
188942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (getActiveNetworkInfo() == null) {
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
189242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (reason != null) {
189342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_REASON, reason);
189442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
189542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (extraInfo != null) {
189642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, extraInfo);
189742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
189842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (info.isFailover()) {
189942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
190042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            info.setFailover(false);
190142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
1902da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt
1903d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt        if (mNetConfigs[info.getType()].isDefault()) {
1904f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            tryFailover(info.getType());
1905f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            if (mActiveDefaultNetwork != -1) {
1906f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt                NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
1907cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
1908cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            } else {
1909029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt                mDefaultInetConditionPublished = 0;
1910cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt                intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
1911cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt            }
1912da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
1913cc4b4016e4b86db012f94bb889e5ca61ff362171Robert Greenwalt
1914029be81302c7a00901e0af34afc06ddabb2805efRobert Greenwalt        intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
1915961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey
1916961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        final Intent immediateIntent = new Intent(intent);
1917961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
1918961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        sendStickyBroadcast(immediateIntent);
19190f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        sendStickyBroadcast(intent);
1920da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        /*
1921da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * If the failover network is already connected, then immediately send
1922da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         * out a followup broadcast indicating successful failover
1923da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt         */
1924f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt        if (mActiveDefaultNetwork != -1) {
1925f21ef7db777e2c79b2f5acac55dcc310b14eb989Robert Greenwalt            sendConnectedBroadcast(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo());
1926da03c4e4b3d47e6917fdcddecf68f2f52564e3a0Robert Greenwalt        }
19270f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    }
19280f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood
19290f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    private void sendStickyBroadcast(Intent intent) {
19300f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        synchronized(this) {
19311c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            if (!mSystemReady) {
19321c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn                mInitialBroadcast = new Intent(intent);
19330f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood            }
19341c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1935c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (VDBG) {
1936961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey                log("sendStickyBroadcast: action=" + intent.getAction());
1937628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            }
1938628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
1939fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            final long ident = Binder.clearCallingIdentity();
1940fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            try {
1941fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn                mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
1942fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            } finally {
1943fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn                Binder.restoreCallingIdentity(ident);
1944fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            }
19450f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        }
19460f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    }
19470f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood
1948628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    private void sendStickyBroadcastDelayed(Intent intent, int delayMs) {
1949628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        if (delayMs <= 0) {
1950628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            sendStickyBroadcast(intent);
1951628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        } else {
1952c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (VDBG) {
1953961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey                log("sendStickyBroadcastDelayed: delayMs=" + delayMs + ", action="
1954961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey                        + intent.getAction());
1955961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey            }
1956628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville            mHandler.sendMessageDelayed(mHandler.obtainMessage(
1957628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    EVENT_SEND_STICKY_BROADCAST_INTENT, intent), delayMs);
1958628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        }
1959628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville    }
1960628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville
19610f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood    void systemReady() {
19620f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        synchronized(this) {
19630f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood            mSystemReady = true;
19641c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn            if (mInitialBroadcast != null) {
19655ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn                mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL);
19661c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn                mInitialBroadcast = null;
19670f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood            }
19680f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood        }
1969434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        // load the global proxy at startup
1970434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY));
197169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
197269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        // Try bringing up tracker, but if KeyStore isn't ready yet, wait
197369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        // for user to unlock device.
197469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        if (!updateLockdownVpn()) {
197569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT);
197669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            mContext.registerReceiver(mUserPresentReceiver, filter);
197769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
198069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
198169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        @Override
198269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        public void onReceive(Context context, Intent intent) {
198369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            // Try creating lockdown tracker, since user present usually means
198469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            // unlocked keystore.
198569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            if (updateLockdownVpn()) {
198669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                mContext.unregisterReceiver(this);
198769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            }
198869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
198969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    };
199069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
1991da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    private boolean isNewNetTypePreferredOverCurrentNetType(int type) {
1992da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        if ((type != mNetworkPreference &&
1993da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    mNetConfigs[mActiveDefaultNetwork].priority >
1994da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    mNetConfigs[type].priority) ||
1995da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                mNetworkPreference == mActiveDefaultNetwork) return false;
1996da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        return true;
1997da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    }
1998da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff
19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleConnect(NetworkInfo info) {
2000da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        final int newNetType = info.getType();
20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2002da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        setupDataActivityTracking(newNetType);
20030412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // snapshot isFailover, because sendConnectedBroadcast() resets it
20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isFailover = info.isFailover();
2006da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        final NetworkStateTracker thisNet = mNetTrackers[newNetType];
2007fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        final String thisIface = thisNet.getLinkProperties().getInterfaceName();
200842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
200942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // if this is a default net and other default is running
201042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // kill the one not preferred
2011da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        if (mNetConfigs[newNetType].isDefault()) {
2012da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != newNetType) {
2013da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                if (isNewNetTypePreferredOverCurrentNetType(newNetType)) {
201442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    // tear down the other
201542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    NetworkStateTracker otherNet =
201642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                            mNetTrackers[mActiveDefaultNetwork];
2017ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    if (DBG) {
2018ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        log("Policy requires " + otherNet.getNetworkInfo().getTypeName() +
201942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                            " teardown");
2020ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                    }
202142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    if (!teardown(otherNet)) {
2022ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        loge("Network declined teardown request");
202327725e8cd1e2eb3b88186ae8d43e437f130b1f84Robert Greenwalt                        teardown(thisNet);
202442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return;
202542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
2026da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                } else {
2027da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                       // don't accept this one
2028da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                        if (VDBG) {
2029da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                            log("Not broadcasting CONNECT_ACTION " +
2030da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                                "to torn down network " + info.getTypeName());
2031da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                        }
2032da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                        teardown(thisNet);
2033da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                        return;
203414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                }
203514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            }
203614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            synchronized (ConnectivityService.this) {
203714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                // have a new default network, release the transition wakelock in a second
203814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                // if it's held.  The second pause is to allow apps to reconnect over the
203914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                // new network
204014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                if (mNetTransitionWakeLock.isHeld()) {
204114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    mHandler.sendMessageDelayed(mHandler.obtainMessage(
2042f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt                            EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
204314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            mNetTransitionWakeLockSerialNumber, 0),
204414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            1000);
204542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2047da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            mActiveDefaultNetwork = newNetType;
2048d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // this will cause us to come up initially as unconnected and switching
2049d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // to connected after our normal pause unless somebody reports us as reall
2050d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // disconnected
2051d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            mDefaultInetConditionPublished = 0;
2052d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            mDefaultConnectionSequence++;
2053d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            mInetConditionChangeInFlight = false;
2054d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            // Don't do this - if we never sign in stay, grey
2055d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt            //reportNetworkCondition(mActiveDefaultNetwork, 100);
20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
205742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        thisNet.setTeardownRequested(false);
2058d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        updateNetworkSettings(thisNet);
2059da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        handleConnectivityChange(newNetType, false);
2060628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
20611059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey
20621059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey        // notify battery stats service about this network
2063fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey        if (thisIface != null) {
20641059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey            try {
2065da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                BatteryStatsService.getService().noteNetworkInterfaceType(thisIface, newNetType);
20661059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey            } catch (RemoteException e) {
20671059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey                // ignored; service lives in system_server
20681059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey            }
20691059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey        }
20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2072da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    private void handleCaptivePortalTrackerCheck(NetworkInfo info) {
2073da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        if (DBG) log("Captive portal check " + info);
2074da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        int type = info.getType();
2075da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        final NetworkStateTracker thisNet = mNetTrackers[type];
2076da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        if (mNetConfigs[type].isDefault()) {
2077da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
2078da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                if (isNewNetTypePreferredOverCurrentNetType(type)) {
2079da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    if (DBG) log("Captive check on " + info.getTypeName());
20809538bdd3c77968c7673719c580ae653ede4654d6Irfan Sheriff                    mCaptivePortalTracker.detectCaptivePortal(new NetworkInfo(info));
2081da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    return;
2082da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                } else {
2083da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    if (DBG) log("Tear down low priority net " + info.getTypeName());
2084da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    teardown(thisNet);
2085da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    return;
2086da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                }
2087da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff            }
2088da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        }
2089da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff
2090da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        thisNet.captivePortalCheckComplete();
2091da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    }
2092da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff
2093da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    /** @hide */
2094da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    public void captivePortalCheckComplete(NetworkInfo info) {
2095da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        mNetTrackers[info.getType()].captivePortalCheckComplete();
2096da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    }
2097da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff
20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20990412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai     * Setup data activity tracking for the given network interface.
21000412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai     *
21010412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai     * Every {@code setupDataActivityTracking} should be paired with a
21020412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai     * {@link removeDataActivityTracking} for cleanup.
21030412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai     */
21040412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    private void setupDataActivityTracking(int type) {
21050412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        final NetworkStateTracker thisNet = mNetTrackers[type];
21060412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        final String iface = thisNet.getLinkProperties().getInterfaceName();
21070412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
21080412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        final int timeout;
21090412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
21100412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        if (ConnectivityManager.isNetworkTypeMobile(type)) {
2111bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown            timeout = Settings.Global.getInt(mContext.getContentResolver(),
2112bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                                             Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
21130412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                                             0);
21140412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            // Canonicalize mobile network type
21150412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            type = ConnectivityManager.TYPE_MOBILE;
21160412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        } else if (ConnectivityManager.TYPE_WIFI == type) {
2117bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown            timeout = Settings.Global.getInt(mContext.getContentResolver(),
2118bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                                             Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI,
21190412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                                             0);
21200412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        } else {
21210412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            // do not track any other networks
21220412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            timeout = 0;
21230412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        }
21240412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
21250412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        if (timeout > 0 && iface != null) {
21260412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            try {
21270412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                mNetd.addIdleTimer(iface, timeout, Integer.toString(type));
21280412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            } catch (RemoteException e) {
21290412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            }
21300412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        }
21310412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    }
21320412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
21330412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    /**
21340412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai     * Remove data activity tracking when network disconnects.
21350412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai     */
21360412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    private void removeDataActivityTracking(int type) {
21370412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        final NetworkStateTracker net = mNetTrackers[type];
21380412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        final String iface = net.getLinkProperties().getInterfaceName();
21390412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
21400412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        if (iface != null && (ConnectivityManager.isNetworkTypeMobile(type) ||
21410412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                              ConnectivityManager.TYPE_WIFI == type)) {
21420412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            try {
21430412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                // the call fails silently if no idletimer setup for this interface
21440412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                mNetd.removeIdleTimer(iface);
21450412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            } catch (RemoteException e) {
21460412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            }
21470412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        }
21480412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    }
21490412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
21500412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    /**
2151c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * After a change in the connectivity state of a network. We're mainly
2152c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * concerned with making sure that the list of DNS servers is set up
2153c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * according to which networks are connected, and ensuring that the
2154c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt     * right routing table entries exist.
21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2156ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt    private void handleConnectivityChange(int netType, boolean doReset) {
2157e822225f7a01ef088ff01f7613f953d5d89945edWink Saville        int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0;
2158e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
216042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         * If a non-default network is enabled, add the host routes that
2161c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt         * will allow it's DNS servers to be accessed.
21629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2163c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        handleDnsConfigurationChange(netType);
216442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
21650a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        LinkProperties curLp = mCurrentLinkProperties[netType];
21660a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        LinkProperties newLp = null;
21670a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
2168c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
21690a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            newLp = mNetTrackers[netType].getLinkProperties();
2170e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            if (VDBG) {
2171e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
2172e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        " doReset=" + doReset + " resetMask=" + resetMask +
2173e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        "\n   curLp=" + curLp +
2174e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        "\n   newLp=" + newLp);
2175e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            }
2176e822225f7a01ef088ff01f7613f953d5d89945edWink Saville
21770a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (curLp != null) {
21780a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                if (curLp.isIdenticalInterfaceName(newLp)) {
21790a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    CompareResult<LinkAddress> car = curLp.compareAddresses(newLp);
21800a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    if ((car.removed.size() != 0) || (car.added.size() != 0)) {
21810a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        for (LinkAddress linkAddr : car.removed) {
21820a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            if (linkAddr.getAddress() instanceof Inet4Address) {
21830a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                resetMask |= NetworkUtils.RESET_IPV4_ADDRESSES;
21840a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            }
21850a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            if (linkAddr.getAddress() instanceof Inet6Address) {
21860a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                resetMask |= NetworkUtils.RESET_IPV6_ADDRESSES;
21870a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            }
2188e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        }
21890a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        if (DBG) {
21900a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            log("handleConnectivityChange: addresses changed" +
21910a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                    " linkProperty[" + netType + "]:" + " resetMask=" + resetMask +
21920a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                    "\n   car=" + car);
21930a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        }
21940a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    } else {
21950a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        if (DBG) {
21960a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                            log("handleConnectivityChange: address are the same reset per doReset" +
21970a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                   " linkProperty[" + netType + "]:" +
21980a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                                   " resetMask=" + resetMask);
2199e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                        }
2200e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                    }
2201e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                } else {
22020a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                    resetMask = NetworkUtils.RESET_ALL_ADDRESSES;
220358d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                    if (DBG) {
220458d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                        log("handleConnectivityChange: interface not not equivalent reset both" +
220558d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                                " linkProperty[" + netType + "]:" +
220658d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                                " resetMask=" + resetMask);
220758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                    }
2208e822225f7a01ef088ff01f7613f953d5d89945edWink Saville                }
2209e822225f7a01ef088ff01f7613f953d5d89945edWink Saville            }
2210d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (mNetConfigs[netType].isDefault()) {
22114c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                handleApplyDefaultProxy(newLp.getHttpProxy());
2212c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            }
2213c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        } else {
22140a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            if (VDBG) {
22150a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
22160a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        " doReset=" + doReset + " resetMask=" + resetMask +
22170a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        "\n  curLp=" + curLp +
22180a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt                        "\n  newLp= null");
221942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22210a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        mCurrentLinkProperties[netType] = newLp;
2222f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt        boolean resetDns = updateRoutes(newLp, curLp, mNetConfigs[netType].isDefault());
2223ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt
22240c074e68437f1a705a8e73ac32e8e4dec370ec43Chia-chi Yeh        if (resetMask != 0 || resetDns) {
2225ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
2226ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            if (linkProperties != null) {
2227ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                String iface = linkProperties.getInterfaceName();
2228ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                if (TextUtils.isEmpty(iface) == false) {
22290c074e68437f1a705a8e73ac32e8e4dec370ec43Chia-chi Yeh                    if (resetMask != 0) {
2230f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                        if (DBG) log("resetConnections(" + iface + ", " + resetMask + ")");
2231f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                        NetworkUtils.resetConnections(iface, resetMask);
22320c074e68437f1a705a8e73ac32e8e4dec370ec43Chia-chi Yeh
22330c074e68437f1a705a8e73ac32e8e4dec370ec43Chia-chi Yeh                        // Tell VPN the interface is down. It is a temporary
22340c074e68437f1a705a8e73ac32e8e4dec370ec43Chia-chi Yeh                        // but effective fix to make VPN aware of the change.
22350c074e68437f1a705a8e73ac32e8e4dec370ec43Chia-chi Yeh                        if ((resetMask & NetworkUtils.RESET_IPV4_ADDRESSES) != 0) {
22360c074e68437f1a705a8e73ac32e8e4dec370ec43Chia-chi Yeh                            mVpn.interfaceStatusChanged(iface, false);
22370c074e68437f1a705a8e73ac32e8e4dec370ec43Chia-chi Yeh                        }
2238f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                    }
2239f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                    if (resetDns) {
2240c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                        if (VDBG) log("resetting DNS cache for " + iface);
2241f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                        try {
2242f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                            mNetd.flushInterfaceDnsCache(iface);
2243f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                        } catch (Exception e) {
2244f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                            // never crash - catch them all
2245c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                            if (DBG) loge("Exception resetting dns cache: " + e);
2246f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                        }
2247f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                    }
2248ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt                }
2249ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt            }
2250ec896c6a863b3cc0a55538a19879e2112b5b8658Robert Greenwalt        }
22511ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo
22521ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        // TODO: Temporary notifying upstread change to Tethering.
22531ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        //       @see bug/4455071
22541ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        /** Notify TetheringService if interface name has been changed. */
22551ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
2256a639b311e93ad14d9ee5c2b2c215ed2d86c32d2aWink Saville                             PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
22571ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo            if (isTetheringSupported()) {
22581ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                mTethering.handleTetherIfaceChange();
22591ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo            }
22601ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo        }
22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22630a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt    /**
22640a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * Add and remove routes using the old properties (null if not previously connected),
22650a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * new properties (null if becoming disconnected).  May even be double null, which
22660a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * is a noop.
22670a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * Uses isLinkDefault to determine if default routes should be set or conversely if
22680a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     * host routes should be set to the dns servers
2269f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt     * returns a boolean indicating the routes changed
22700a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt     */
2271f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt    private boolean updateRoutes(LinkProperties newLp, LinkProperties curLp,
2272f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt            boolean isLinkDefault) {
22730a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        Collection<RouteInfo> routesToAdd = null;
2274ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        CompareResult<InetAddress> dnsDiff = new CompareResult<InetAddress>();
2275ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
22760a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (curLp != null) {
22770a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // check for the delta between the current set and the new
2278ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            routeDiff = curLp.compareRoutes(newLp);
22790a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            dnsDiff = curLp.compareDnses(newLp);
2280ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        } else if (newLp != null) {
2281ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            routeDiff.added = newLp.getRoutes();
2282ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            dnsDiff.added = newLp.getDnses();
2283d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
2284d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
2285f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt        boolean routesChanged = (routeDiff.removed.size() != 0 || routeDiff.added.size() != 0);
2286f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt
2287ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        for (RouteInfo r : routeDiff.removed) {
2288ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (isLinkDefault || ! r.isDefaultRoute()) {
22893b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                removeRoute(curLp, r, TO_DEFAULT_TABLE);
22903b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            }
22913b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            if (isLinkDefault == false) {
22923b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                // remove from a secondary route table
22933b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                removeRoute(curLp, r, TO_SECONDARY_TABLE);
2294d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
2295ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        }
229659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
2297ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt        for (RouteInfo r :  routeDiff.added) {
2298ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt            if (isLinkDefault || ! r.isDefaultRoute()) {
22993b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                addRoute(newLp, r, TO_DEFAULT_TABLE);
2300e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt            } else {
23013b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                // add to a secondary route table
23023b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt                addRoute(newLp, r, TO_SECONDARY_TABLE);
23033b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt
2304e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                // many radios add a default route even when we don't want one.
2305e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                // remove the default route unless somebody else has asked for it
2306e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                String ifaceName = newLp.getInterfaceName();
2307e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                if (TextUtils.isEmpty(ifaceName) == false && mAddedRoutes.contains(r) == false) {
2308c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    if (VDBG) log("Removing " + r + " for interface " + ifaceName);
2309e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                    try {
2310e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                        mNetd.removeRoute(ifaceName, r);
2311e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                    } catch (Exception e) {
2312e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                        // never crash - catch them all
23138beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt                        if (DBG) loge("Exception trying to remove a route: " + e);
2314e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                    }
2315e6b2429cf719f30259a3eae61b94524b5cff4fabRobert Greenwalt                }
231659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            }
2317d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
2318d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
23190a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt        if (!isLinkDefault) {
23200a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt            // handle DNS routes
2321f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt            if (routesChanged) {
2322ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                // routes changed - remove all old dns entries and add new
2323ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                if (curLp != null) {
2324ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    for (InetAddress oldDns : curLp.getDnses()) {
2325ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                        removeRouteToAddress(curLp, oldDns);
2326ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    }
2327ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                }
2328ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                if (newLp != null) {
2329ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    for (InetAddress newDns : newLp.getDnses()) {
2330ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                        addRouteToAddress(newLp, newDns);
2331ad55d35114237071133eb28ded93a014185d4e35Robert Greenwalt                    }
2332edcb4f9d560a85970030e1df70426e8d1e2267d2Robert Greenwalt                }
2333f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt            } else {
2334f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                // no change in routes, check for change in dns themselves
2335f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                for (InetAddress oldDns : dnsDiff.removed) {
2336f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                    removeRouteToAddress(curLp, oldDns);
2337f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                }
2338f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                for (InetAddress newDns : dnsDiff.added) {
2339f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                    addRouteToAddress(newLp, newDns);
2340f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt                }
2341d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
2342d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
2343f125a093636ef22c81a9d90397407f9ef05a6e9aRobert Greenwalt        return routesChanged;
2344d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
2345d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
23460a46db5d88461d9a6c85bb2e95982ac4c511d57eRobert Greenwalt
2347d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff   /**
2348d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * Reads the network specific TCP buffer sizes from SystemProperties
2349d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
2350d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * wide use
2351d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     */
2352d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff   public void updateNetworkSettings(NetworkStateTracker nt) {
2353d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        String key = nt.getTcpBufferSizesPropName();
2354899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey        String bufferSizes = key == null ? null : SystemProperties.get(key);
2355d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
2356899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey        if (TextUtils.isEmpty(bufferSizes)) {
235758d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) log(key + " not found in system properties. Using defaults");
2358d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
2359d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            // Setting to default values so we won't be stuck to previous values
2360d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            key = "net.tcp.buffersize.default";
2361d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            bufferSizes = SystemProperties.get(key);
2362d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
2363d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
2364d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        // Set values in kernel
2365d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        if (bufferSizes.length() != 0) {
236658d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) {
2367ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                log("Setting TCP values: [" + bufferSizes
2368d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff                        + "] which comes from [" + key + "]");
2369d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
2370d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            setBufferSize(bufferSizes);
2371d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
2372d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
2373d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
2374d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff   /**
2375d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
2376d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
2377d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     *
2378d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     * @param bufferSizes in the format of "readMin, readInitial, readMax,
2379d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     *        writeMin, writeInitial, writeMax"
2380d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff     */
2381d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    private void setBufferSize(String bufferSizes) {
2382d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        try {
2383d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            String[] values = bufferSizes.split(",");
2384d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
2385d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            if (values.length == 6) {
2386d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff              final String prefix = "/sys/kernel/ipv4/tcp_";
2387da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "rmem_min", values[0]);
2388da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "rmem_def", values[1]);
2389da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "rmem_max", values[2]);
2390da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "wmem_min", values[3]);
2391da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "wmem_def", values[4]);
2392da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood                FileUtils.stringToFile(prefix + "wmem_max", values[5]);
2393d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            } else {
2394ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                loge("Invalid buffersize string: " + bufferSizes);
2395d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff            }
2396d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        } catch (IOException e) {
2397ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville            loge("Can't set tcp buffer sizes:" + e);
2398d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff        }
2399d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff    }
2400d649c12815bcf944b2c97371f3f60716a42a1557Irfan Sheriff
240142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    /**
240242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * Adjust the per-process dns entries (net.dns<x>.<pid>) based
240342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * on the highest priority active net which this process requested.
240442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     * If there aren't any, clear it out
240542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt     */
240642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private void reassessPidDns(int myPid, boolean doBump)
240742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    {
240858d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (VDBG) log("reassessPidDns for pid " + myPid);
240942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        for(int i : mPriorityList) {
2410d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (mNetConfigs[i].isDefault()) {
241142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                continue;
241242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
241342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            NetworkStateTracker nt = mNetTrackers[i];
241442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (nt.getNetworkInfo().isConnected() &&
241542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    !nt.isTeardownRequested()) {
241637e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt                LinkProperties p = nt.getLinkProperties();
241747f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                if (p == null) continue;
241842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                List pids = mNetRequestersPids[i];
241942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                for (int j=0; j<pids.size(); j++) {
242042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    Integer pid = (Integer)pids.get(j);
242142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    if (pid.intValue() == myPid) {
242247f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt                        Collection<InetAddress> dnses = p.getDnses();
2423c1358b240c28443496249a5483afaccfc93f8d97Lorenzo Colitti                        writePidDns(dnses, myPid);
242442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        if (doBump) {
242542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                            bumpDns();
242642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        }
242742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                        return;
242842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    }
242942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
243042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt           }
243142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
243242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // nothing found - delete
243342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        for (int i = 1; ; i++) {
243442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            String prop = "net.dns" + i + "." + myPid;
243542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            if (SystemProperties.get(prop).length() == 0) {
243642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                if (doBump) {
243742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                    bumpDns();
243842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                }
243942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                return;
244042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
244142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            SystemProperties.set(prop, "");
244242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
244342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
244442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
24451039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt    // return true if results in a change
2446c1358b240c28443496249a5483afaccfc93f8d97Lorenzo Colitti    private boolean writePidDns(Collection <InetAddress> dnses, int pid) {
244742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int j = 1;
24481039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt        boolean changed = false;
244947f69fe2999e46004f2f2463b70d38de9ff7079aRobert Greenwalt        for (InetAddress dns : dnses) {
24501039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            String dnsString = dns.getHostAddress();
24511039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            if (changed || !dnsString.equals(SystemProperties.get("net.dns" + j + "." + pid))) {
24521039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                changed = true;
24537b72ea71b90f1c12ad9b104cc2e79499d98de863yoonsung.nam                SystemProperties.set("net.dns" + j + "." + pid, dns.getHostAddress());
24541039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            }
24557b72ea71b90f1c12ad9b104cc2e79499d98de863yoonsung.nam            j++;
245642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
24571039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt        return changed;
245842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
245942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
246042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private void bumpDns() {
24619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
246242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         * Bump the property that tells the name resolver library to reread
246342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt         * the DNS server list from the properties.
24649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
246542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String propVal = SystemProperties.get("net.dnschange");
246642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        int n = 0;
246742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if (propVal.length() != 0) {
246842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            try {
246942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                n = Integer.parseInt(propVal);
247042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } catch (NumberFormatException e) {}
247142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
247242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        SystemProperties.set("net.dnschange", "" + (n+1));
247303595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        /*
247403595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt         * Tell the VMs to toss their DNS caches
247503595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt         */
247603595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        Intent intent = new Intent(Intent.ACTION_CLEAR_DNS_CACHE);
247703595d01188d88c169e8c9dd51b357fd545e69ccRobert Greenwalt        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
24783d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt        /*
24793d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt         * Connectivity events can happen before boot has completed ...
24803d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt         */
24813d1db8672aa1d285d387c8aef5a8bfac72997d18Stan Chesnutt        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2482fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        final long ident = Binder.clearCallingIdentity();
2483fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        try {
2484fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
2485fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        } finally {
2486fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            Binder.restoreCallingIdentity(ident);
2487fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        }
248842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
24899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    // Caller must grab mDnsLock.
2491a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt    private boolean updateDns(String network, String iface,
2492c1358b240c28443496249a5483afaccfc93f8d97Lorenzo Colitti            Collection<InetAddress> dnses, String domains) {
249344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        boolean changed = false;
249444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        int last = 0;
249544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        if (dnses.size() == 0 && mDefaultDns != null) {
249644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            ++last;
249744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            String value = mDefaultDns.getHostAddress();
249844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (!value.equals(SystemProperties.get("net.dns1"))) {
249944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                if (DBG) {
250058d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                    loge("no dns provided for " + network + " - using " + value);
250144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
250244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                changed = true;
250344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                SystemProperties.set("net.dns1", value);
250444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
250544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        } else {
250644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            for (InetAddress dns : dnses) {
250744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                ++last;
250844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                String key = "net.dns" + last;
250944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                String value = dns.getHostAddress();
251044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                if (!changed && value.equals(SystemProperties.get(key))) {
251144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    continue;
251244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
251358d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt                if (VDBG) {
251444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    log("adding dns " + value + " for " + network);
251544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
251644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                changed = true;
251744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                SystemProperties.set(key, value);
251844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
251944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        }
252044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        for (int i = last + 1; i <= mNumDnsEntries; ++i) {
252144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            String key = "net.dns" + i;
252258d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt            if (VDBG) log("erasing " + key);
252344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            changed = true;
252444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            SystemProperties.set(key, "");
252544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        }
252644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        mNumDnsEntries = last;
252744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
2528a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        if (changed) {
2529a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            try {
2530a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses));
2531a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                mNetd.setDefaultInterfaceForDns(iface);
2532a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            } catch (Exception e) {
25338beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt                if (DBG) loge("exception setting default dns interface: " + e);
2534a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt            }
2535a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt        }
253644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        if (!domains.equals(SystemProperties.get("net.dns.search"))) {
253744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            SystemProperties.set("net.dns.search", domains);
253844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            changed = true;
253944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        }
254044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        return changed;
254144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh    }
254244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
2543c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt    private void handleDnsConfigurationChange(int netType) {
254442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        // add default net's dns entries
2545c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        NetworkStateTracker nt = mNetTrackers[netType];
2546c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt        if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
254737e65ebb7eb932e1a144b1cab262e11ca5fd109bRobert Greenwalt            LinkProperties p = nt.getLinkProperties();
2548c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            if (p == null) return;
2549c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            Collection<InetAddress> dnses = p.getDnses();
25501039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            boolean changed = false;
2551d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt            if (mNetConfigs[netType].isDefault()) {
255244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                String network = nt.getNetworkInfo().getTypeName();
255344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                synchronized (mDnsLock) {
255444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    if (!mDnsOverridden) {
2555c1358b240c28443496249a5483afaccfc93f8d97Lorenzo Colitti                        changed = updateDns(network, p.getInterfaceName(), dnses, "");
25561039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt                    }
2557c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                }
2558c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt            } else {
25591efe4d5cfd3913b3c4efa7aee4bf9fea262c0ad2Robert Greenwalt                try {
2560c59c6da9ae14097c77eee69285c6eacc8130936cRobert Greenwalt                    mNetd.setDnsServersForInterface(p.getInterfaceName(),
2561a10b7fd2239668a87be690a57ef7b3bc39b6bfd3Robert Greenwalt                            NetworkUtils.makeStrings(dnses));
25621efe4d5cfd3913b3c4efa7aee4bf9fea262c0ad2Robert Greenwalt                } catch (Exception e) {
25638beff9586ff89a1e59469e9820fd9e9d704300d2Robert Greenwalt                    if (DBG) loge("exception setting dns servers: " + e);
2564c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                }
2565c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                // set per-pid dns for attached secondary nets
2566c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                List pids = mNetRequestersPids[netType];
2567c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                for (int y=0; y< pids.size(); y++) {
2568c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                    Integer pid = (Integer)pids.get(y);
2569c1358b240c28443496249a5483afaccfc93f8d97Lorenzo Colitti                    changed = writePidDns(dnses, pid.intValue());
25709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
25719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
25721039872f597995cab2f88b9c841f8c2b8e71c451Robert Greenwalt            if (changed) bumpDns();
25739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
257442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    }
257542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
2576f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt    private int getRestoreDefaultNetworkDelay(int networkType) {
257742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        String restoreDefaultNetworkDelayStr = SystemProperties.get(
257842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                NETWORK_RESTORE_DELAY_PROP_NAME);
257942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        if(restoreDefaultNetworkDelayStr != null &&
258042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                restoreDefaultNetworkDelayStr.length() != 0) {
258142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            try {
258242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                return Integer.valueOf(restoreDefaultNetworkDelayStr);
258342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            } catch (NumberFormatException e) {
258442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2586f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        // if the system property isn't set, use the value for the apn type
2587f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        int ret = RESTORE_DEFAULT_NETWORK_DELAY;
2588f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt
2589f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) &&
2590f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt                (mNetConfigs[networkType] != null)) {
2591f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt            ret = mNetConfigs[networkType].restoreTime;
2592f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        }
2593f2102f7a1a26d399cc60c516ed7d90ef660de055Robert Greenwalt        return ret;
25949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2597e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
2598e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
259986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt        if (mContext.checkCallingOrSelfPermission(
260086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                android.Manifest.permission.DUMP)
26019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                != PackageManager.PERMISSION_GRANTED) {
260286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt            pw.println("Permission Denial: can't dump ConnectivityService " +
260386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    "from from pid=" + Binder.getCallingPid() + ", uid=" +
260486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    Binder.getCallingUid());
26059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
26069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2607e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey
2608e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey        // TODO: add locking to get atomic snapshot
26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pw.println();
2610e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey        for (int i = 0; i < mNetTrackers.length; i++) {
2611e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            final NetworkStateTracker nst = mNetTrackers[i];
2612b928535902b204ac3ec25f161352786842248767Robert Greenwalt            if (nst != null) {
2613e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                pw.println("NetworkStateTracker for " + getNetworkTypeName(i) + ":");
2614e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                pw.increaseIndent();
2615b928535902b204ac3ec25f161352786842248767Robert Greenwalt                if (nst.getNetworkInfo().isConnected()) {
2616b928535902b204ac3ec25f161352786842248767Robert Greenwalt                    pw.println("Active network: " + nst.getNetworkInfo().
2617b928535902b204ac3ec25f161352786842248767Robert Greenwalt                            getTypeName());
2618b928535902b204ac3ec25f161352786842248767Robert Greenwalt                }
2619b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pw.println(nst.getNetworkInfo());
2620e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                pw.println(nst.getLinkProperties());
2621b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pw.println(nst);
2622b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pw.println();
2623e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                pw.decreaseIndent();
2624b928535902b204ac3ec25f161352786842248767Robert Greenwalt            }
2625b928535902b204ac3ec25f161352786842248767Robert Greenwalt        }
2626b928535902b204ac3ec25f161352786842248767Robert Greenwalt
2627b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println("Network Requester Pids:");
2628e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey        pw.increaseIndent();
2629b928535902b204ac3ec25f161352786842248767Robert Greenwalt        for (int net : mPriorityList) {
2630b928535902b204ac3ec25f161352786842248767Robert Greenwalt            String pidString = net + ": ";
2631b928535902b204ac3ec25f161352786842248767Robert Greenwalt            for (Object pid : mNetRequestersPids[net]) {
2632b928535902b204ac3ec25f161352786842248767Robert Greenwalt                pidString = pidString + pid.toString() + ", ";
263342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            }
2634b928535902b204ac3ec25f161352786842248767Robert Greenwalt            pw.println(pidString);
26359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2636b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println();
2637e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey        pw.decreaseIndent();
2638b928535902b204ac3ec25f161352786842248767Robert Greenwalt
2639b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println("FeatureUsers:");
2640e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey        pw.increaseIndent();
2641b928535902b204ac3ec25f161352786842248767Robert Greenwalt        for (Object requester : mFeatureUsers) {
2642b928535902b204ac3ec25f161352786842248767Robert Greenwalt            pw.println(requester.toString());
2643b928535902b204ac3ec25f161352786842248767Robert Greenwalt        }
2644b928535902b204ac3ec25f161352786842248767Robert Greenwalt        pw.println();
2645e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey        pw.decreaseIndent();
26462a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
264714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        synchronized (this) {
264814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            pw.println("NetworkTranstionWakeLock is currently " +
264914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
265014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
265114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        }
265214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        pw.println();
265314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
26542a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        mTethering.dump(fd, pw, args);
26554e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt
26564e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        if (mInetLog != null) {
26574e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            pw.println();
26584e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            pw.println("Inet condition reports:");
2659e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            pw.increaseIndent();
26604e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            for(int i = 0; i < mInetLog.size(); i++) {
26614e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                pw.println(mInetLog.get(i));
26624e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            }
2663e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            pw.decreaseIndent();
26644e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        }
26659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
266742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    // must be stateless - things change under us.
26684c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private class NetworkStateTrackerHandler extends Handler {
26694c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        public NetworkStateTrackerHandler(Looper looper) {
2670bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville            super(looper);
2671bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville        }
2672bb08caf54bdb201d9b85393152f1b400eb4abe2bWink Saville
26739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
26749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void handleMessage(Message msg) {
26759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NetworkInfo info;
26769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (msg.what) {
26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case NetworkStateTracker.EVENT_STATE_CHANGED:
26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    info = (NetworkInfo) msg.obj;
2679511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    int type = info.getType();
2680511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    NetworkInfo.State state = info.getState();
2681511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt
2682c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    if (VDBG || (state == NetworkInfo.State.CONNECTED) ||
2683c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                            (state == NetworkInfo.State.DISCONNECTED)) {
2684c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                        log("ConnectivityChange for " +
268586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                            info.getTypeName() + ": " +
2686511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                            state + "/" + info.getDetailedState());
2687c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    }
26889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Connectivity state changed:
26903bc9a79fe83d19d4701bd6035fd30d83f267906eRobert Greenwalt                    // [31-14] Reserved for future use
26913bc9a79fe83d19d4701bd6035fd30d83f267906eRobert Greenwalt                    // [13-10] Network subtype (for mobile network, as defined
269286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    //         by TelephonyManager)
26933bc9a79fe83d19d4701bd6035fd30d83f267906eRobert Greenwalt                    // [9-4] Detailed state ordinal (as defined by
269486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    //         NetworkInfo.DetailedState)
26953bc9a79fe83d19d4701bd6035fd30d83f267906eRobert Greenwalt                    // [3-0] Network type (as defined by ConnectivityManager)
26963bc9a79fe83d19d4701bd6035fd30d83f267906eRobert Greenwalt                    int eventLogParam = (info.getType() & 0xf) |
26973bc9a79fe83d19d4701bd6035fd30d83f267906eRobert Greenwalt                            ((info.getDetailedState().ordinal() & 0x3f) << 4) |
26983bc9a79fe83d19d4701bd6035fd30d83f267906eRobert Greenwalt                            (info.getSubtype() << 10);
2699ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker                    EventLog.writeEvent(EventLogTags.CONNECTIVITY_STATE_CHANGED,
270086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                            eventLogParam);
270186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt
270286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                    if (info.getDetailedState() ==
270386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                            NetworkInfo.DetailedState.FAILED) {
27049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleConnectionFailure(info);
2705da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                    } else if (info.getDetailedState() ==
2706da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                            DetailedState.CAPTIVE_PORTAL_CHECK) {
2707da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff                        handleCaptivePortalTrackerCheck(info);
2708511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    } else if (state == NetworkInfo.State.DISCONNECTED) {
27099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleDisconnect(info);
2710511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    } else if (state == NetworkInfo.State.SUSPENDED) {
27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // TODO: need to think this over.
271286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // the logic here is, handle SUSPENDED the same as
271386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // DISCONNECTED. The only difference being we are
271486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // broadcasting an intent with NetworkInfo that's
271586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // suspended. This allows the applications an
271686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // opportunity to handle DISCONNECTED and SUSPENDED
271786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt                        // differently, or not.
27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleDisconnect(info);
2719511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt                    } else if (state == NetworkInfo.State.CONNECTED) {
27209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        handleConnect(info);
27219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
272269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                    if (mLockdownTracker != null) {
272369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                        mLockdownTracker.onNetworkInfoChanged(info);
272469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                    }
27259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
27269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED:
2727c76b8fa911bb2501ba55153d3ac25a5132daa3a9Robert Greenwalt                    info = (NetworkInfo) msg.obj;
27281ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    // TODO: Temporary allowing network configuration
27291ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    //       change not resetting sockets.
27301ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    //       @see bug/4455071
27311ccb10e25d5af8ef1d997b0ed2291dbbcaacf44eKazuhiro Ondo                    handleConnectivityChange(info.getType(), false);
27329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
2733d14e17627266ff8cf804d1f8241a0a4bde7a0ab4Robert Greenwalt                case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED:
2734d14e17627266ff8cf804d1f8241a0a4bde7a0ab4Robert Greenwalt                    info = (NetworkInfo) msg.obj;
2735d14e17627266ff8cf804d1f8241a0a4bde7a0ab4Robert Greenwalt                    type = info.getType();
2736d14e17627266ff8cf804d1f8241a0a4bde7a0ab4Robert Greenwalt                    updateNetworkSettings(mNetTrackers[type]);
2737d14e17627266ff8cf804d1f8241a0a4bde7a0ab4Robert Greenwalt                    break;
27384c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey            }
27394c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        }
27404c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    }
27414c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey
27424c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey    private class InternalHandler extends Handler {
27434c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        public InternalHandler(Looper looper) {
27444c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey            super(looper);
27454c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        }
27464c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey
27474c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        @Override
27484c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey        public void handleMessage(Message msg) {
27494c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey            NetworkInfo info;
27504c628eba480d271d5547af5d4fafc01e0e53a5ebJeff Sharkey            switch (msg.what) {
2751f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt                case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
275214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    String causedBy = null;
275314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    synchronized (ConnectivityService.this) {
275414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                        if (msg.arg1 == mNetTransitionWakeLockSerialNumber &&
275514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                                mNetTransitionWakeLock.isHeld()) {
275614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            mNetTransitionWakeLock.release();
275714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                            causedBy = mNetTransitionWakeLockCausedBy;
275814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                        }
275914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    }
276014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    if (causedBy != null) {
2761ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville                        log("NetTransition Wakelock for " + causedBy + " released by timeout");
276214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    }
2763057d5e9824a01a03c13d5a32d3c7f5023d01586eRobert Greenwalt                    break;
27648dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_RESTORE_DEFAULT_NETWORK:
27659c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    FeatureUser u = (FeatureUser)msg.obj;
27669c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt                    u.expire();
2767d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                    break;
27688dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_INET_CONDITION_CHANGE:
27698dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
27708dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int netType = msg.arg1;
27718dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int condition = msg.arg2;
27728dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleInetConditionChange(netType, condition);
2773d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                    break;
27748dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
27758dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_INET_CONDITION_HOLD_END:
27768dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
27778dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int netType = msg.arg1;
27788dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int sequence = msg.arg2;
27798dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleInetConditionHoldEnd(netType, sequence);
2780d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                    break;
27818dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
27828dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_SET_NETWORK_PREFERENCE:
27838dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
27848dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    int preference = msg.arg1;
27858dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleSetNetworkPreference(preference);
27868dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    break;
27878dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
27888dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                case EVENT_SET_MOBILE_DATA:
27898dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                {
27908dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    boolean enabled = (msg.arg1 == ENABLED);
27918dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    handleSetMobileData(enabled);
279214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                    break;
27938dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                }
2794434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                case EVENT_APPLY_GLOBAL_HTTP_PROXY:
2795434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                {
2796434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    handleDeprecatedGlobalHttpProxy();
2797d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    break;
2798d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                }
2799d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                case EVENT_SET_DEPENDENCY_MET:
2800d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                {
2801d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    boolean met = (msg.arg1 == ENABLED);
2802d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    handleSetDependencyMet(msg.arg2, met);
2803d55a6b498d66d8fc415908ecf63e50f46cce67e8Robert Greenwalt                    break;
2804434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                }
280544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                case EVENT_RESTORE_DNS:
280644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                {
280744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    if (mActiveDefaultNetwork != -1) {
280844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                        handleDnsConfigurationChange(mActiveDefaultNetwork);
280944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    }
281044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    break;
281144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
2812628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                case EVENT_SEND_STICKY_BROADCAST_INTENT:
2813628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                {
2814628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    Intent intent = (Intent)msg.obj;
2815628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    sendStickyBroadcast(intent);
2816628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                    break;
2817628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville                }
28188e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                case EVENT_SET_POLICY_DATA_ENABLE: {
28198e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                    final int networkType = msg.arg1;
28208e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                    final boolean enabled = msg.arg2 == ENABLED;
28218e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                    handleSetPolicyDataEnable(networkType, enabled);
282269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                    break;
282369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                }
282469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                case EVENT_VPN_STATE_CHANGED: {
282569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                    if (mLockdownTracker != null) {
282669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                        mLockdownTracker.onVpnStateChanged((NetworkInfo) msg.obj);
282769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                    }
282869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                    break;
28298e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey                }
28309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
28329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2833d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
2834d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // javadoc from interface
28355a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public int tether(String iface) {
2836d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        enforceTetherChangePermission();
28375a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
28385a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        if (isTetheringSupported()) {
28395a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return mTethering.tether(iface);
28405a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        } else {
28415a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
28425a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        }
2843d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
2844d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
2845d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // javadoc from interface
28465a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public int untether(String iface) {
2847d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        enforceTetherChangePermission();
28485a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
28495a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        if (isTetheringSupported()) {
28505a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return mTethering.untether(iface);
28515a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        } else {
28525a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
28535a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        }
28545a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    }
28555a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
28565a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    // javadoc from interface
28575a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public int getLastTetherError(String iface) {
28585a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        enforceTetherAccessPermission();
28595a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
28605a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        if (isTetheringSupported()) {
28615a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return mTethering.getLastTetherError(iface);
28625a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        } else {
28635a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
28645a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        }
28652a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
28662a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
28672a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // TODO - proper iface API for selection by property, inspection, etc
28682a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    public String[] getTetherableUsbRegexs() {
28692a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
28702a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        if (isTetheringSupported()) {
28712a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return mTethering.getTetherableUsbRegexs();
28722a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        } else {
28732a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return new String[0];
28742a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        }
28752a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
28762a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
28772a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    public String[] getTetherableWifiRegexs() {
28782a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
28792a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        if (isTetheringSupported()) {
28802a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return mTethering.getTetherableWifiRegexs();
28812a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        } else {
28822a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt            return new String[0];
28836fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        }
28846fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    }
28856fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang
28866fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang    public String[] getTetherableBluetoothRegexs() {
28876fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        enforceTetherAccessPermission();
28886fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        if (isTetheringSupported()) {
28896fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang            return mTethering.getTetherableBluetoothRegexs();
28906fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang        } else {
28916fdd0c6274c81b337ad35b70480f881daf7354c3Danica Chang            return new String[0];
28922a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        }
2893d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
2894d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
28956c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood    public int setUsbTethering(boolean enable) {
28966c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        enforceTetherAccessPermission();
28976c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        if (isTetheringSupported()) {
28986c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood            return mTethering.setUsbTethering(enable);
28996c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        } else {
29006c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood            return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
29016c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood        }
29026c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood    }
29036c2260b3af3a9243aa7f04cf03106f31817cb4c1Mike Lockwood
2904d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // TODO - move iface listing, queries, etc to new module
2905d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    // javadoc from interface
2906d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    public String[] getTetherableIfaces() {
29072a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
2908d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        return mTethering.getTetherableIfaces();
2909d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
2910d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt
2911d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    public String[] getTetheredIfaces() {
29122a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
2913d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt        return mTethering.getTetheredIfaces();
2914d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt    }
29152a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt
2916cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    @Override
2917cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    public String[] getTetheredIfacePairs() {
2918cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        enforceTetherAccessPermission();
2919cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        return mTethering.getTetheredIfacePairs();
2920cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    }
2921cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey
29225a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    public String[] getTetheringErroredIfaces() {
29235a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        enforceTetherAccessPermission();
29245a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt        return mTethering.getErroredIfaces();
29255a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt    }
29265a73506cdd466f2b96686ced3ff0f7ca224d1143Robert Greenwalt
29272a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // if ro.tether.denied = true we default to no tethering
29282a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // gservices could set the secure setting to 1 though to enable it on a build where it
29292a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    // had previously been turned off.
29302a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    public boolean isTetheringSupported() {
29312a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        enforceTetherAccessPermission();
29322a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt        int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
2933bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown        boolean tetherEnabledInSettings = (Settings.Global.getInt(mContext.getContentResolver(),
2934bf6f6f9de72c9fd15e6bda9f228c05a9b37d6324Jeff Brown                Settings.Global.TETHER_SUPPORTED, defaultVal) != 0);
2935c9d5fb7c95f158d9a31d534895373afcfad77806Robert Greenwalt        return tetherEnabledInSettings && mTetheringConfigValid;
29362a091d7aa0c174986387e5d56bf97a87fe075bdbRobert Greenwalt    }
293714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt
293814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // An API NetworkStateTrackers can call when they lose their network.
293914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // This will automatically be cleared after X seconds or a network becomes CONNECTED,
294014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // whichever happens first.  The timer is started by the first caller and not
294114f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    // restarted by subsequent callers.
294214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    public void requestNetworkTransitionWakelock(String forWhom) {
294314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        enforceConnectivityInternalPermission();
294414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        synchronized (this) {
294514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            if (mNetTransitionWakeLock.isHeld()) return;
294614f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            mNetTransitionWakeLockSerialNumber++;
294714f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            mNetTransitionWakeLock.acquire();
294814f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt            mNetTransitionWakeLockCausedBy = forWhom;
294914f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        }
295014f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        mHandler.sendMessageDelayed(mHandler.obtainMessage(
2951f333123d50776507891b90a6eda4a3b8fa305bb6Robert Greenwalt                EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
295214f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                mNetTransitionWakeLockSerialNumber, 0),
295314f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt                mNetTransitionWakeLockTimeout);
295414f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt        return;
295514f2ef4c9da27a3d58d65dc9f684c5f764ee279aRobert Greenwalt    }
2956ca4306c976d393c3cd04270bc2de0af2f4f30fa5Robert Greenwalt
2957d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    // 100 percent is full good, 0 is full bad.
2958d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    public void reportInetCondition(int networkType, int percentage) {
295958d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (VDBG) log("reportNetworkCondition(" + networkType + ", " + percentage + ")");
2960d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt        mContext.enforceCallingOrSelfPermission(
2961d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                android.Manifest.permission.STATUS_BAR,
2962d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt                "ConnectivityService");
2963d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt
29644e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        if (DBG) {
29654e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            int pid = getCallingPid();
29664e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            int uid = getCallingUid();
29674e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            String s = pid + "(" + uid + ") reports inet is " +
29684e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                (percentage > 50 ? "connected" : "disconnected") + " (" + percentage + ") on " +
29694e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                "network Type " + networkType + " at " + GregorianCalendar.getInstance().getTime();
29704e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            mInetLog.add(s);
29714e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            while(mInetLog.size() > INET_CONDITION_LOG_MAX_SIZE) {
29724e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt                mInetLog.remove(0);
29734e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt            }
29744e8dfefb06227a911eb5abfcb2591d8eae5db42bRobert Greenwalt        }
2975d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt        mHandler.sendMessage(mHandler.obtainMessage(
29768dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            EVENT_INET_CONDITION_CHANGE, networkType, percentage));
29778dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
29788dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
29798dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleInetConditionChange(int netType, int condition) {
29808dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mActiveDefaultNetwork == -1) {
2981c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (DBG) log("handleInetConditionChange: no active default network - ignore");
29828dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
29838dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
29848dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mActiveDefaultNetwork != netType) {
2985c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (DBG) log("handleInetConditionChange: net=" + netType +
2986c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                            " != default=" + mActiveDefaultNetwork + " - ignore");
29878dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
29888dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
2989c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville        if (VDBG) {
2990c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            log("handleInetConditionChange: net=" +
2991c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    netType + ", condition=" + condition +
2992c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    ",mActiveDefaultNetwork=" + mActiveDefaultNetwork);
2993c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville        }
29948dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mDefaultInetCondition = condition;
29958dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        int delay;
29968dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mInetConditionChangeInFlight == false) {
2997c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (VDBG) log("handleInetConditionChange: starting a change hold");
29988dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            // setup a new hold to debounce this
29998dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            if (mDefaultInetCondition > 50) {
3000625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                delay = Settings.Global.getInt(mContext.getContentResolver(),
3001625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                        Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY, 500);
30028dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            } else {
3003625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                delay = Settings.Global.getInt(mContext.getContentResolver(),
3004625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                        Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY, 3000);
30058dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            }
30068dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            mInetConditionChangeInFlight = true;
30078dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_INET_CONDITION_HOLD_END,
30088dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt                    mActiveDefaultNetwork, mDefaultConnectionSequence), delay);
30098dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        } else {
3010c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            // we've set the new condition, when this hold ends that will get picked up
3011c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (VDBG) log("handleInetConditionChange: currently in hold - not setting new end evt");
30128dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
30138dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    }
30148dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
30158dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt    private void handleInetConditionHoldEnd(int netType, int sequence) {
3016c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville        if (DBG) {
3017c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            log("handleInetConditionHoldEnd: net=" + netType +
3018c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    ", condition=" + mDefaultInetCondition +
3019c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville                    ", published condition=" + mDefaultInetConditionPublished);
30208dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
30218dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mInetConditionChangeInFlight = false;
30228dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt
30238dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mActiveDefaultNetwork == -1) {
3024c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (DBG) log("handleInetConditionHoldEnd: no active default network - ignoring");
30258dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
30268dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
30278dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (mDefaultConnectionSequence != sequence) {
3028c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (DBG) log("handleInetConditionHoldEnd: event hold for obsolete network - ignoring");
30298dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
30308dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
3031628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        // TODO: Figure out why this optimization sometimes causes a
3032628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //       change in mDefaultInetCondition to be missed and the
3033628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //       UI to not be updated.
3034628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //if (mDefaultInetConditionPublished == mDefaultInetCondition) {
3035628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //    if (DBG) log("no change in condition - aborting");
3036628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //    return;
3037628b08530a50bddbe3d65088a8b621c0950e0c19Wink Saville        //}
30388dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        NetworkInfo networkInfo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
30398dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        if (networkInfo.isConnected() == false) {
3040c9acde9aa6cf21598640aeebb7d908f1926a48ddWink Saville            if (DBG) log("handleInetConditionHoldEnd: default network not connected - ignoring");
30418dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt            return;
30428dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        }
30438dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        mDefaultInetConditionPublished = mDefaultInetCondition;
30448dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        sendInetConditionBroadcast(networkInfo);
30458dcc28be065bb5997ed97d58c9592324b891023aRobert Greenwalt        return;
3046d7085fcf6567452a9d6fc69b0c6b1bf556f4c1b9Robert Greenwalt    }
3047434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
30484c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh    public ProxyProperties getProxy() {
30494c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh        synchronized (mDefaultProxyLock) {
30504c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            return mDefaultProxyDisabled ? null : mDefaultProxy;
30514c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh        }
3052434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
3053434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
3054434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    public void setGlobalProxy(ProxyProperties proxyProperties) {
3055434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        enforceChangePermission();
3056434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        synchronized (mGlobalProxyLock) {
3057434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (proxyProperties == mGlobalProxy) return;
3058434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
3059434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
3060434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
3061434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String host = "";
3062434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            int port = 0;
3063434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String exclList = "";
3064434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (proxyProperties != null && !TextUtils.isEmpty(proxyProperties.getHost())) {
3065434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mGlobalProxy = new ProxyProperties(proxyProperties);
3066434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                host = mGlobalProxy.getHost();
3067434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                port = mGlobalProxy.getPort();
3068434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                exclList = mGlobalProxy.getExclusionList();
3069434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            } else {
3070434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                mGlobalProxy = null;
3071434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            }
3072434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            ContentResolver res = mContext.getContentResolver();
3073625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey            Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host);
3074625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey            Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port);
3075625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey            Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
3076434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    exclList);
3077434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
3078434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
3079434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (mGlobalProxy == null) {
3080434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            proxyProperties = mDefaultProxy;
3081434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
3082e4474c3b7098a13bc81b0dba35bacd93b8a22f79Chia-chi Yeh        //sendProxyBroadcast(proxyProperties);
3083434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
3084434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
3085b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt    private void loadGlobalProxy() {
3086b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        ContentResolver res = mContext.getContentResolver();
3087625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey        String host = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST);
3088625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey        int port = Settings.Global.getInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, 0);
3089625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey        String exclList = Settings.Global.getString(res,
3090625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
3091b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        if (!TextUtils.isEmpty(host)) {
3092b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            ProxyProperties proxyProperties = new ProxyProperties(host, port, exclList);
3093b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            synchronized (mGlobalProxyLock) {
3094b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt                mGlobalProxy = proxyProperties;
3095b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt            }
3096b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt        }
3097b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt    }
3098b7090d68be1046e7b8743620592bb63c8256eeabRobert Greenwalt
3099434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    public ProxyProperties getGlobalProxy() {
3100434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        synchronized (mGlobalProxyLock) {
3101434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            return mGlobalProxy;
3102434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
3103434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
3104434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
31054c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh    private void handleApplyDefaultProxy(ProxyProperties proxy) {
31064c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh        if (proxy != null && TextUtils.isEmpty(proxy.getHost())) {
31074c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            proxy = null;
31084c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh        }
31094c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh        synchronized (mDefaultProxyLock) {
3110434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
3111434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (mDefaultProxy == proxy) return;
31124c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            mDefaultProxy = proxy;
31134c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh
31144c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            if (!mDefaultProxyDisabled) {
31154c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                sendProxyBroadcast(proxy);
3116434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            }
3117434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
3118434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
3119434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
3120434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private void handleDeprecatedGlobalHttpProxy() {
3121625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey        String proxy = Settings.Global.getString(mContext.getContentResolver(),
3122625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                Settings.Global.HTTP_PROXY);
3123434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (!TextUtils.isEmpty(proxy)) {
3124434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String data[] = proxy.split(":");
3125434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            String proxyHost =  data[0];
3126434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            int proxyPort = 8080;
3127434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            if (data.length > 1) {
3128434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                try {
3129434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    proxyPort = Integer.parseInt(data[1]);
3130434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                } catch (NumberFormatException e) {
3131434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                    return;
3132434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                }
3133434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            }
3134434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            ProxyProperties p = new ProxyProperties(data[0], proxyPort, "");
3135434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            setGlobalProxy(p);
3136434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
3137434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
3138434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
3139434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private void sendProxyBroadcast(ProxyProperties proxy) {
314055985bed7be8c93296eee3f4f39557fba4fbaebeRobert Greenwalt        if (proxy == null) proxy = new ProxyProperties("", 0, "");
314158d4c595818de0d1b7edf382fee6ed1a4bd70e7fRobert Greenwalt        if (DBG) log("sending Proxy Broadcast for " + proxy);
3142434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
3143b35d67a8a773f2d3127a119b424a86b3e56fe563Stan Chesnutt        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
3144b35d67a8a773f2d3127a119b424a86b3e56fe563Stan Chesnutt            Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
3145434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
3146fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        final long ident = Binder.clearCallingIdentity();
3147fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        try {
3148fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
3149fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        } finally {
3150fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn            Binder.restoreCallingIdentity(ident);
3151fd8bf5c790749b0382c9d70424cac2367d6276e3Dianne Hackborn        }
3152434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
3153434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
3154434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    private static class SettingsObserver extends ContentObserver {
3155434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        private int mWhat;
3156434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        private Handler mHandler;
3157434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        SettingsObserver(Handler handler, int what) {
3158434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            super(handler);
3159434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            mHandler = handler;
3160434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            mWhat = what;
3161434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
3162434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
3163434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        void observe(Context context) {
3164434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            ContentResolver resolver = context.getContentResolver();
3165625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey            resolver.registerContentObserver(Settings.Global.getUriFor(
3166625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey                    Settings.Global.HTTP_PROXY), false, this);
3167434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
3168434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt
3169434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        @Override
3170434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        public void onChange(boolean selfChange) {
3171434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            mHandler.obtainMessage(mWhat).sendToTarget();
3172434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
3173434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt    }
3174ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville
3175fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private static void log(String s) {
3176ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        Slog.d(TAG, s);
3177ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    }
3178ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville
3179fb878b66b9456f8fee2bcb1076263852d207949dJeff Sharkey    private static void loge(String s) {
3180ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville        Slog.e(TAG, s);
3181ed9c02b56c6f56a583aa272f82818ef039face75Wink Saville    }
3182ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
3183aea743aaa43a833fd8ff3dc56205197583152d5frepo sync    int convertFeatureToNetworkType(int networkType, String feature) {
3184aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        int usedNetworkType = networkType;
3185aea743aaa43a833fd8ff3dc56205197583152d5frepo sync
3186aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        if(networkType == ConnectivityManager.TYPE_MOBILE) {
3187aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
3188aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS;
3189aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
3190aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL;
3191aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
3192aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                    TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
3193aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN;
3194aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
3195aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
3196aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_FOTA)) {
3197aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_FOTA;
3198aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_IMS)) {
3199aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_IMS;
3200aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_CBS)) {
3201aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_MOBILE_CBS;
3202aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else {
3203aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                Slog.e(TAG, "Can't match any mobile netTracker!");
3204aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            }
3205aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } else if (networkType == ConnectivityManager.TYPE_WIFI) {
3206aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            if (TextUtils.equals(feature, "p2p")) {
3207aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                usedNetworkType = ConnectivityManager.TYPE_WIFI_P2P;
3208aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            } else {
3209aea743aaa43a833fd8ff3dc56205197583152d5frepo sync                Slog.e(TAG, "Can't match any wifi netTracker!");
3210aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            }
3211aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        } else {
3212aea743aaa43a833fd8ff3dc56205197583152d5frepo sync            Slog.e(TAG, "Unexpected network type");
3213aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        }
3214aea743aaa43a833fd8ff3dc56205197583152d5frepo sync        return usedNetworkType;
32152b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville    }
3216c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey
3217c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    private static <T> T checkNotNull(T value, String message) {
3218c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        if (value == null) {
3219c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey            throw new NullPointerException(message);
3220c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        }
3221c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey        return value;
3222c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey    }
3223ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
322404ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    /**
322504ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * Protect a socket from VPN routing rules. This method is used by
32262e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * VpnBuilder and not available in ConnectivityManager. Permissions
32272e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * are checked in Vpn class.
322804ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * @hide
322904ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     */
3230ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    @Override
32315779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh    public boolean protectVpn(ParcelFileDescriptor socket) {
323269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        throwIfLockdownEnabled();
32335779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        try {
32345779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            int type = mActiveDefaultNetwork;
32355779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            if (ConnectivityManager.isNetworkTypeValid(type)) {
32365779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                mVpn.protect(socket, mNetTrackers[type].getLinkProperties().getInterfaceName());
32375779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                return true;
32385779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            }
32395779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        } catch (Exception e) {
32405779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            // ignore
32415779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        } finally {
32425779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            try {
32435779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                socket.close();
32445779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            } catch (Exception e) {
32455779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh                // ignore
32465779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh            }
32475779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        }
32485779c9c2d9f1f7a28279fe907aebbb43981286fdChia-chi Yeh        return false;
3249ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
3250ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
325104ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    /**
325204ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * Prepare for a VPN application. This method is used by VpnDialogs
32532e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * and not available in ConnectivityManager. Permissions are checked
32542e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * in Vpn class.
325504ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * @hide
325604ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     */
3257ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    @Override
3258100155a310fbb5028fc48e359bdfb7c4d3531843Chia-chi Yeh    public boolean prepareVpn(String oldPackage, String newPackage) {
325969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        throwIfLockdownEnabled();
3260100155a310fbb5028fc48e359bdfb7c4d3531843Chia-chi Yeh        return mVpn.prepare(oldPackage, newPackage);
3261ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
3262ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
326304ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    /**
326404ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * Configure a TUN interface and return its file descriptor. Parameters
326504ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * are encoded and opaque to this class. This method is used by VpnBuilder
32662e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * and not available in ConnectivityManager. Permissions are checked in
32672e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Vpn class.
326804ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     * @hide
326904ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh     */
3270ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    @Override
327104ba25c418bc4538e9dc0f047cfb9608d358f679Chia-chi Yeh    public ParcelFileDescriptor establishVpn(VpnConfig config) {
327269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        throwIfLockdownEnabled();
3273ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        return mVpn.establish(config);
3274ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
3275ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
327677fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh    /**
327782f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey     * Start legacy VPN, controlling native daemons as needed. Creates a
327882f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey     * secondary thread to perform connection work, returning quickly.
32792e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     */
32802e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    @Override
328182f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey    public void startLegacyVpn(VpnProfile profile) {
328269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        throwIfLockdownEnabled();
328382f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        final LinkProperties egress = getActiveLinkProperties();
328482f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        if (egress == null) {
328582f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey            throw new IllegalStateException("Missing active network connection");
328682f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        }
328782f8521d386f3109147c477d04e5e90e5c715fa0Jeff Sharkey        mVpn.startLegacyVpn(profile, mKeyStore, egress);
32882e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    }
32892e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh
32902e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    /**
32912e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * Return the information of the ongoing legacy VPN. This method is used
32922e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * by VpnSettings and not available in ConnectivityManager. Permissions
32932e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh     * are checked in Vpn class.
329477fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh     * @hide
329577fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh     */
329677fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh    @Override
32972e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh    public LegacyVpnInfo getLegacyVpnInfo() {
329869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        throwIfLockdownEnabled();
32992e46764a707bd14cad22bc179669eeecb2d7c647Chia-chi Yeh        return mVpn.getLegacyVpnInfo();
330077fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh    }
330177fd485c2ff780d1e6ef0ba1e3e811370ecbc528Chia-chi Yeh
3302ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    /**
3303ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * Callback for VPN subsystem. Currently VPN is not adapted to the service
3304ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * through NetworkStateTracker since it works differently. For example, it
3305ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * needs to override DNS servers but never takes the default routes. It
3306ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * relies on another data network, and it could keep existing connections
3307ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * alive after reconnecting, switching between networks, or even resuming
3308ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * from deep sleep. Calls from applications should be done synchronously
3309ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * to avoid race conditions. As these are all hidden APIs, refactoring can
3310ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     * be done whenever a better abstraction is developed.
3311ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh     */
3312ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    public class VpnCallback {
3313ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        private VpnCallback() {
3314ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        }
3315ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
3316899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey        public void onStateChanged(NetworkInfo info) {
331769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            mHandler.obtainMessage(EVENT_VPN_STATE_CHANGED, info).sendToTarget();
3318899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey        }
3319899223b97c9b0ae56a8211a46600914c0ecfd854Jeff Sharkey
332044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        public void override(List<String> dnsServers, List<String> searchDomains) {
332144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (dnsServers == null) {
332244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                restore();
332344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                return;
332444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
332544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
332644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // Convert DNS servers into addresses.
332744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            List<InetAddress> addresses = new ArrayList<InetAddress>();
332844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            for (String address : dnsServers) {
332944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                // Double check the addresses and remove invalid ones.
333044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                try {
333144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    addresses.add(InetAddress.parseNumericAddress(address));
333244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                } catch (Exception e) {
333344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    // ignore
333444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
333544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
333644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (addresses.isEmpty()) {
333744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                restore();
333844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                return;
333944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
334044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
334144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // Concatenate search domains into a string.
334244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            StringBuilder buffer = new StringBuilder();
334344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (searchDomains != null) {
334444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                for (String domain : searchDomains) {
334544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                    buffer.append(domain).append(' ');
334644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
334744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
334844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            String domains = buffer.toString().trim();
334944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
335044bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            // Apply DNS changes.
335144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            boolean changed = false;
335244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            synchronized (mDnsLock) {
3353c1358b240c28443496249a5483afaccfc93f8d97Lorenzo Colitti                changed = updateDns("VPN", "VPN", addresses, domains);
335444bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                mDnsOverridden = true;
335544bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
335644bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            if (changed) {
335744bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                bumpDns();
335844bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
335944bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh
33604c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            // Temporarily disable the default proxy.
33614c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            synchronized (mDefaultProxyLock) {
33624c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                mDefaultProxyDisabled = true;
33634c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                if (mDefaultProxy != null) {
33644c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                    sendProxyBroadcast(null);
33654c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                }
33664c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            }
33674c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh
33684c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            // TODO: support proxy per network.
3369ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        }
3370ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh
337144bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh        public void restore() {
337244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            synchronized (mDnsLock) {
33734c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                if (mDnsOverridden) {
33744c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                    mDnsOverridden = false;
33754c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                    mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
33764c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                }
33774c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            }
33784c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh            synchronized (mDefaultProxyLock) {
33794c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                mDefaultProxyDisabled = false;
33804c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                if (mDefaultProxy != null) {
33814c12a47bffc51868285b17db9f00d40affc7c9e3Chia-chi Yeh                    sendProxyBroadcast(mDefaultProxy);
338244bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh                }
338344bb251be76894967ea57a3c904377e32325bc3eChia-chi Yeh            }
3384ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh        }
3385ff3bdca31f4cf2bd607519b276dd175763aa1784Chia-chi Yeh    }
338669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
338769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    @Override
338869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    public boolean updateLockdownVpn() {
3389f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        enforceSystemUid();
339069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
339169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        // Tear down existing lockdown if profile was removed
339269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        mLockdownEnabled = LockdownVpnTracker.isEnabled();
339369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        if (mLockdownEnabled) {
339469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            if (mKeyStore.state() != KeyStore.State.UNLOCKED) {
339569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                Slog.w(TAG, "KeyStore locked; unable to create LockdownTracker");
339669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                return false;
339769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            }
339869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
339969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            final String profileName = new String(mKeyStore.get(Credentials.LOCKDOWN_VPN));
340069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            final VpnProfile profile = VpnProfile.decode(
340169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                    profileName, mKeyStore.get(Credentials.VPN + profileName));
340269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, mVpn, profile));
340369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        } else {
340469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            setLockdownTracker(null);
340569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
340669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
340769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        return true;
340869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    }
340969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
341069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    /**
341169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     * Internally set new {@link LockdownVpnTracker}, shutting down any existing
341269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown.
341369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey     */
341469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    private void setLockdownTracker(LockdownVpnTracker tracker) {
341569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        // Shutdown any existing tracker
341669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        final LockdownVpnTracker existing = mLockdownTracker;
341769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        mLockdownTracker = null;
341869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        if (existing != null) {
341969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            existing.shutdown();
342069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
342169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
342269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        try {
342369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            if (tracker != null) {
342469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                mNetd.setFirewallEnabled(true);
342569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                mLockdownTracker = tracker;
342669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                mLockdownTracker.init();
342769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            } else {
342869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey                mNetd.setFirewallEnabled(false);
342969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            }
343069ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        } catch (RemoteException e) {
343169ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            // ignored; NMS lives inside system_server
343269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
343369ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    }
343469ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey
343569ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    private void throwIfLockdownEnabled() {
343669ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        if (mLockdownEnabled) {
343769ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey            throw new IllegalStateException("Unavailable in lockdown mode");
343869ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        }
343969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey    }
3440f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey
3441f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey    private static void enforceSystemUid() {
3442f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        final int uid = Binder.getCallingUid();
3443f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        if (uid != Process.SYSTEM_UID) {
3444f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey            throw new SecurityException("Only available to AID_SYSTEM");
3445f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        }
3446f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey    }
34479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3448