1873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat/*
2873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Copyright (C) 2007 The Android Open Source Project
3873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat *
4873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * you may not use this file except in compliance with the License.
6873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * You may obtain a copy of the License at
7873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat *
8873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
9873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat *
10873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Unless required by applicable law or agreed to in writing, software
11873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * See the License for the specific language governing permissions and
14873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * limitations under the License.
15873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */
16873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
17873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatpackage com.android.server;
18873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
194529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkeyimport static android.Manifest.permission.CONNECTIVITY_INTERNAL;
2047eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkeyimport static android.Manifest.permission.DUMP;
21af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkeyimport static android.Manifest.permission.SHUTDOWN;
22b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_DEFAULT;
23d0c5b9abed60b7bc056d026bf0f2b2235410fb70Dianne Hackbornimport static android.net.NetworkStats.TAG_ALL;
241b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkStats.TAG_NONE;
251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkStats.UID_ALL;
26ae2c1810839430c84e4a1172580d9c4b18f568caJeff Sharkeyimport static android.net.TrafficStats.UID_TETHERING;
274b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colittiimport static android.net.RouteInfo.RTN_THROW;
284b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colittiimport static android.net.RouteInfo.RTN_UNICAST;
294b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colittiimport static android.net.RouteInfo.RTN_UNREACHABLE;
3079751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colittiimport static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
31ba2896e939f359e5857149f1a27212db71be012bJeff Sharkeyimport static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
32ba2896e939f359e5857149f1a27212db71be012bJeff Sharkeyimport static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
33ba2896e939f359e5857149f1a27212db71be012bJeff Sharkeyimport static com.android.server.NetworkManagementService.NetdResponseCode.IpFwdStatusResult;
34ba2896e939f359e5857149f1a27212db71be012bJeff Sharkeyimport static com.android.server.NetworkManagementService.NetdResponseCode.TetherDnsFwdTgtListResult;
35ba2896e939f359e5857149f1a27212db71be012bJeff Sharkeyimport static com.android.server.NetworkManagementService.NetdResponseCode.TetherInterfaceListResult;
36ba2896e939f359e5857149f1a27212db71be012bJeff Sharkeyimport static com.android.server.NetworkManagementService.NetdResponseCode.TetherStatusResult;
37e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkeyimport static com.android.server.NetworkManagementService.NetdResponseCode.TetheringStatsListResult;
38ba2896e939f359e5857149f1a27212db71be012bJeff Sharkeyimport static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
39a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
401b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
41873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.content.Context;
4277b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackbornimport android.net.ConnectivityManager;
434d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehatimport android.net.INetworkManagementEventObserver;
44eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkeyimport android.net.InterfaceConfiguration;
45c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colittiimport android.net.IpPrefix;
46ed1264093234b1f1354cd5f669eb82a50bb56869Robert Greenwaltimport android.net.LinkAddress;
47b57edc5ae999abd9c7310833f4f10bbacbc469d7Lorenzo Colittiimport android.net.Network;
48eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkeyimport android.net.NetworkStats;
49ed1264093234b1f1354cd5f669eb82a50bb56869Robert Greenwaltimport android.net.NetworkUtils;
5059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwaltimport android.net.RouteInfo;
516bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensenimport android.net.UidRange;
529ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriffimport android.net.wifi.WifiConfiguration;
539ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriffimport android.net.wifi.WifiConfiguration.KeyMgmt;
5491268cf21eace600792d04db1ac62e9268f48002Dianne Hackbornimport android.os.BatteryStats;
55f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkeyimport android.os.Binder;
56b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkeyimport android.os.Handler;
5777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackbornimport android.os.INetworkActivityListener;
58873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.os.INetworkManagementService;
5977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackbornimport android.os.PowerManager;
60f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkeyimport android.os.Process;
613df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkeyimport android.os.RemoteCallbackList;
623df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkeyimport android.os.RemoteException;
637a1c3fce478122b9f03464117dc94d44f7c1995eJeff Sharkeyimport android.os.ServiceManager;
649a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport android.os.SystemClock;
6562dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissenimport android.os.SystemProperties;
662ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackbornimport android.telephony.DataConnectionRealTimeInfo;
672ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackbornimport android.telephony.PhoneStateListener;
68fb40dd4d00bd3361b2535bc866e6c21eadc52558Wink Savilleimport android.telephony.SubscriptionManager;
6967e0789cd3870af2fbbdefbff28f6fde9095a015Wink Savilleimport android.telephony.TelephonyManager;
709ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriffimport android.util.Log;
718a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
72b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkeyimport android.util.SparseBooleanArray;
73873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
747a1c3fce478122b9f03464117dc94d44f7c1995eJeff Sharkeyimport com.android.internal.app.IBatteryStats;
751059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkeyimport com.android.internal.net.NetworkStatsFactory;
76c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkeyimport com.android.internal.util.Preconditions;
77ba2896e939f359e5857149f1a27212db71be012bJeff Sharkeyimport com.android.server.NativeDaemonConnector.Command;
7856cd646abeae51e806791f82ab0995fe047b1fe4Jeff Sharkeyimport com.android.server.NativeDaemonConnector.SensitiveArg;
7969ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkeyimport com.android.server.net.LockdownVpnTracker;
80b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkeyimport com.google.android.collect.Maps;
814414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
8259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwaltimport java.io.BufferedReader;
8359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwaltimport java.io.DataInputStream;
84873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.io.File;
8547eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkeyimport java.io.FileDescriptor;
869a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport java.io.FileInputStream;
879a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport java.io.IOException;
889a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport java.io.InputStreamReader;
8947eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkeyimport java.io.PrintWriter;
9059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwaltimport java.net.Inet4Address;
9142065ac64cba166dc0fe602957ea8fe80bf406e2Sreeram Ramachandranimport java.net.Inet6Address;
92eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkeyimport java.net.InetAddress;
933b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwaltimport java.net.InterfaceAddress;
943b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwaltimport java.net.NetworkInterface;
953b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwaltimport java.net.SocketException;
96eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkeyimport java.util.ArrayList;
976bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensenimport java.util.Arrays;
98b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkeyimport java.util.HashMap;
991da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguoimport java.util.List;
100b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkeyimport java.util.Map;
101eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkeyimport java.util.NoSuchElementException;
102eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkeyimport java.util.StringTokenizer;
103e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwaltimport java.util.concurrent.CountDownLatch;
104873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
105873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat/**
106873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * @hide
107873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */
1088e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkeypublic class NetworkManagementService extends INetworkManagementService.Stub
1098e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        implements Watchdog.Monitor {
110eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey    private static final String TAG = "NetworkManagementService";
111cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn    private static final boolean DBG = false;
112305bcbf0c961840c4505770d084a1caacc074dbbKenny Root    private static final String NETD_TAG = "NetdConnector";
1137421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    private static final String NETD_SOCKET_NAME = "netd";
114305bcbf0c961840c4505770d084a1caacc074dbbKenny Root
1156bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    private static final int MAX_UID_RANGES_PER_COMMAND = 10;
1166bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
1178e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
1188e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Name representing {@link #setGlobalAlert(long)} limit when delivered to
1198e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * {@link INetworkManagementEventObserver#limitReached(String, String)}.
1208e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
1218e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
1228e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
123873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    class NetdResponseCode {
12403666c705ddabe0e7c5869ab69c2ca8b964164e9Sreeram Ramachandran        /* Keep in sync with system/netd/server/ResponseCode.h */
125873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        public static final int InterfaceListResult       = 110;
126873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        public static final int TetherInterfaceListResult = 111;
127873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        public static final int TetherDnsFwdTgtListResult = 112;
12872759df749bb8557269db86c2e3b2a8a0343cc26San Mehat        public static final int TtyListResult             = 113;
129e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey        public static final int TetheringStatsListResult  = 114;
130873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
131873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        public static final int TetherStatusResult        = 210;
132873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        public static final int IpFwdStatusResult         = 211;
133ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat        public static final int InterfaceGetCfgResult     = 213;
134e325392c257a5460de6327420c81729f4e687881Robert Greenwalt        public static final int SoftapStatusResult        = 214;
13591cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat        public static final int InterfaceRxCounterResult  = 216;
13691cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat        public static final int InterfaceTxCounterResult  = 217;
137cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        public static final int QuotaCounterResult        = 220;
138cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        public static final int TetheringStatsResult      = 221;
13984c00c67d70af4797c098f20124b9f8882980649Selim Gurun        public static final int DnsProxyQueryResult       = 222;
14079751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        public static final int ClatdStatusResult         = 223;
141e325392c257a5460de6327420c81729f4e687881Robert Greenwalt
142e325392c257a5460de6327420c81729f4e687881Robert Greenwalt        public static final int InterfaceChange           = 600;
14312b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall        public static final int BandwidthControl          = 601;
1446b7358d9511df7e519bb417fbed6017c06a33d45Haoyu Bai        public static final int InterfaceClassActivity    = 613;
1455c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti        public static final int InterfaceAddressChange    = 614;
1465ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        public static final int InterfaceDnsServerInfo    = 615;
147c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        public static final int RouteChange               = 616;
148873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
149873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1502ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn    static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
1512ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn
152873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    /**
153873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat     * Binder context for this service
154873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat     */
1552ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn    private final Context mContext;
156873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
157873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    /**
158873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat     * connector object for communicating with netd
159873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat     */
1602ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn    private final NativeDaemonConnector mConnector;
161873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1622c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt    private final Handler mFgHandler;
1632ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn    private final Handler mDaemonHandler;
1642ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn    private final PhoneStateListener mPhoneStateListener;
165b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey
166e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn    private IBatteryStats mBatteryStats;
167e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn
1682ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn    private final Thread mThread;
169b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey    private CountDownLatch mConnectedSignal = new CountDownLatch(1);
170e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt
1713df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey    private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
1723df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey            new RemoteCallbackList<INetworkManagementEventObserver>();
1734d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
1741059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey    private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
1751059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey
17641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private Object mQuotaLock = new Object();
177b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    /** Set of interfaces with active quotas. */
178b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey    private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
17941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    /** Set of interfaces with active alerts. */
180b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey    private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
181b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    /** Set of UIDs with active reject rules. */
182b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
183b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
1840412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    private Object mIdleTimerLock = new Object();
1850412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    /** Set of interfaces with active idle timers. */
1860412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    private static class IdleTimerParams {
1870412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        public final int timeout;
18877b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        public final int type;
1890412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        public int networkCount;
1900412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
19177b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        IdleTimerParams(int timeout, int type) {
1920412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            this.timeout = timeout;
19377b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            this.type = type;
1940412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            this.networkCount = 1;
1950412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        }
1960412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    }
1970412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
1980412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
199fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey    private volatile boolean mBandwidthControlEnabled;
200c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    private volatile boolean mFirewallEnabled;
201350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
2022ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn    private boolean mMobileActivityFromRadio = false;
2032ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn    private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
2042ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn
20577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
20677b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            new RemoteCallbackList<INetworkActivityListener>();
20777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    private boolean mNetworkActive;
20877b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
209873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    /**
210873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat     * Constructs a new NetworkManagementService instance
211873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat     *
212873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat     * @param context  Binder context for this service
213873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat     */
2147421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    private NetworkManagementService(Context context, String socket) {
215873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        mContext = context;
2164d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
2172c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        // make sure this is on the same looper as our NativeDaemonConnector for sync purposes
2182c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        mFgHandler = new Handler(FgThread.get().getLooper());
2192c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt
22062dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen        if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
2212ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            mConnector = null;
2222ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            mThread = null;
2232ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            mDaemonHandler = null;
2242ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            mPhoneStateListener = null;
22562dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen            return;
22662dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen        }
22762dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen
2284590e52f3d0558e01322fe4dd55bb612afdfb079Dianne Hackborn        // Don't need this wake lock, since we now have a time stamp for when
2294590e52f3d0558e01322fe4dd55bb612afdfb079Dianne Hackborn        // the network actually went inactive.  (It might be nice to still do this,
2304590e52f3d0558e01322fe4dd55bb612afdfb079Dianne Hackborn        // but I don't want to do it through the power manager because that pollutes the
2314590e52f3d0558e01322fe4dd55bb612afdfb079Dianne Hackborn        // battery stats history with pointless noise.)
2322ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        //PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
2334590e52f3d0558e01322fe4dd55bb612afdfb079Dianne Hackborn        PowerManager.WakeLock wl = null; //pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NETD_TAG);
23477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
235873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        mConnector = new NativeDaemonConnector(
2362ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160, wl,
2372ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                FgThread.get().getLooper());
238e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt        mThread = new Thread(mConnector, NETD_TAG);
239fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey
2402ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        mDaemonHandler = new Handler(FgThread.get().getLooper());
24167e0789cd3870af2fbbdefbff28f6fde9095a015Wink Saville
242d09c4cad65c708f2c4810d24295456708a2000d2Wink Saville        mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
243fb40dd4d00bd3361b2535bc866e6c21eadc52558Wink Saville                mDaemonHandler.getLooper()) {
24467e0789cd3870af2fbbdefbff28f6fde9095a015Wink Saville            @Override
2452ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            public void onDataConnectionRealTimeInfoChanged(
2462ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    DataConnectionRealTimeInfo dcRtInfo) {
24767e0789cd3870af2fbbdefbff28f6fde9095a015Wink Saville                if (DBG) Slog.d(TAG, "onDataConnectionRealTimeInfoChanged: " + dcRtInfo);
2482d4b4ed681efcfb64c4d2b4d2a2d236aae1dc7eeDianne Hackborn                notifyInterfaceClassActivity(ConnectivityManager.TYPE_MOBILE,
2492d4b4ed681efcfb64c4d2b4d2a2d236aae1dc7eeDianne Hackborn                        dcRtInfo.getDcPowerState(), dcRtInfo.getTime(), true);
2502ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            }
2512ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        };
25267e0789cd3870af2fbbdefbff28f6fde9095a015Wink Saville        TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
25367e0789cd3870af2fbbdefbff28f6fde9095a015Wink Saville        if (tm != null) {
25467e0789cd3870af2fbbdefbff28f6fde9095a015Wink Saville            tm.listen(mPhoneStateListener,
25567e0789cd3870af2fbbdefbff28f6fde9095a015Wink Saville                    PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO);
25667e0789cd3870af2fbbdefbff28f6fde9095a015Wink Saville        }
2572ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn
258fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey        // Add ourself to the Watchdog monitors.
259fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey        Watchdog.getInstance().addMonitor(this);
260e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt    }
261e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt
2627421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    static NetworkManagementService create(Context context,
2637421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti            String socket) throws InterruptedException {
2647421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        final NetworkManagementService service = new NetworkManagementService(context, socket);
265b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        final CountDownLatch connectedSignal = service.mConnectedSignal;
266e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt        if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
267e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt        service.mThread.start();
268e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt        if (DBG) Slog.d(TAG, "Awaiting socket connection");
269b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        connectedSignal.await();
270e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt        if (DBG) Slog.d(TAG, "Connected");
271e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt        return service;
272873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
273873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
2747421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    public static NetworkManagementService create(Context context) throws InterruptedException {
2757421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        return create(context, NETD_SOCKET_NAME);
2767421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    }
2777421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
278350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    public void systemReady() {
279b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        prepareNativeDaemon();
280b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        if (DBG) Slog.d(TAG, "Prepared");
281350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    }
282350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
283e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn    private IBatteryStats getBatteryStats() {
284e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn        synchronized (this) {
285e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn            if (mBatteryStats != null) {
286e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn                return mBatteryStats;
287e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn            }
288e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn            mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
289e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn                    BatteryStats.SERVICE_NAME));
290e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn            return mBatteryStats;
291e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn        }
292e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn    }
293e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn
294af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
2953df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey    public void registerObserver(INetworkManagementEventObserver observer) {
2964529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2973df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey        mObservers.register(observer);
2984d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    }
2994d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
300af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
3013df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey    public void unregisterObserver(INetworkManagementEventObserver observer) {
3024529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
3033df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey        mObservers.unregister(observer);
3044d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    }
3054d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
3064d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    /**
3076143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen     * Notify our observers of an interface status change
3084d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat     */
3096143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen    private void notifyInterfaceStatusChanged(String iface, boolean up) {
3103df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey        final int length = mObservers.beginBroadcast();
3112c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        try {
3122c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            for (int i = 0; i < length; i++) {
3132c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
3142c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                    mObservers.getBroadcastItem(i).interfaceStatusChanged(iface, up);
3152c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
3162c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RuntimeException e) {
3172c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
3186143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen            }
3192c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        } finally {
3202c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            mObservers.finishBroadcast();
3216143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen        }
3226143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen    }
3236143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen
3246143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen    /**
325f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen     * Notify our observers of an interface link state change
3266143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen     * (typically, an Ethernet cable has been plugged-in or unplugged).
3276143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen     */
3286143f5f7392fb0d3e5702a46a2415bd0ecb6efb4Mike J. Chen    private void notifyInterfaceLinkStateChanged(String iface, boolean up) {
3293df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey        final int length = mObservers.beginBroadcast();
3302c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        try {
3312c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            for (int i = 0; i < length; i++) {
3322c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
3332c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                    mObservers.getBroadcastItem(i).interfaceLinkStateChanged(iface, up);
3342c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
3352c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RuntimeException e) {
3362c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
3374d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat            }
3382c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        } finally {
3392c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            mObservers.finishBroadcast();
3404d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat        }
3414d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    }
3424d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
3434d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    /**
3444d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat     * Notify our observers of an interface addition.
3454d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat     */
3464d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    private void notifyInterfaceAdded(String iface) {
3473df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey        final int length = mObservers.beginBroadcast();
3482c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        try {
3492c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            for (int i = 0; i < length; i++) {
3502c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
3512c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                    mObservers.getBroadcastItem(i).interfaceAdded(iface);
3522c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
3532c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RuntimeException e) {
3542c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
3554d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat            }
3562c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        } finally {
3572c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            mObservers.finishBroadcast();
3584d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat        }
3594d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    }
3604d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
3614d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    /**
3624d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat     * Notify our observers of an interface removal.
3634d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat     */
3644d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    private void notifyInterfaceRemoved(String iface) {
36589b8a2161ab6ad0211df305da1eebd6227a217e6Jeff Sharkey        // netd already clears out quota and alerts for removed ifaces; update
36689b8a2161ab6ad0211df305da1eebd6227a217e6Jeff Sharkey        // our sanity-checking state.
367b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        mActiveAlerts.remove(iface);
368b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        mActiveQuotas.remove(iface);
36989b8a2161ab6ad0211df305da1eebd6227a217e6Jeff Sharkey
3703df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey        final int length = mObservers.beginBroadcast();
3712c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        try {
3722c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            for (int i = 0; i < length; i++) {
3732c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
3742c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                    mObservers.getBroadcastItem(i).interfaceRemoved(iface);
3752c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
3762c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RuntimeException e) {
3772c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
3784d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat            }
3792c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        } finally {
3802c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            mObservers.finishBroadcast();
3814d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat        }
3824d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat    }
3834d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
384e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt    /**
38512b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall     * Notify our observers of a limit reached.
38612b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall     */
38712b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall    private void notifyLimitReached(String limitName, String iface) {
3883df273e45864ba595b4d870fa3f6c81a770078e2Jeff Sharkey        final int length = mObservers.beginBroadcast();
3892c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        try {
3902c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            for (int i = 0; i < length; i++) {
3912c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
3922c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                    mObservers.getBroadcastItem(i).limitReached(limitName, iface);
3932c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
3942c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RuntimeException e) {
3952c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
39612b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall            }
3972c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        } finally {
3982c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            mObservers.finishBroadcast();
39912b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall        }
40012b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall    }
40112b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall
40212b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall    /**
403db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai     * Notify our observers of a change in the data activity state of the interface
404db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai     */
4052ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn    private void notifyInterfaceClassActivity(int type, int powerState, long tsNanos,
4062ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            boolean fromRadio) {
4072ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
4082ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        if (isMobile) {
4092ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            if (!fromRadio) {
4102ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                if (mMobileActivityFromRadio) {
4112ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    // If this call is not coming from a report from the radio itself, but we
4122ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    // have previously received reports from the radio, then we will take the
4132ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    // power state to just be whatever the radio last reported.
4142ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    powerState = mLastPowerStateFromRadio;
4152ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                }
4162ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            } else {
4172ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                mMobileActivityFromRadio = true;
4182ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            }
4192ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            if (mLastPowerStateFromRadio != powerState) {
4202ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                mLastPowerStateFromRadio = powerState;
4212c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
4222ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos);
4232c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
4242c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
425db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai            }
4262ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        }
4272ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn
4282ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        boolean isActive = powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
4292ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
4302ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn
4312ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        if (!isMobile || fromRadio || !mMobileActivityFromRadio) {
4322ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            // Report the change in data activity.  We don't do this if this is a change
4332ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            // on the mobile network, that is not coming from the radio itself, and we
4342ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            // have previously seen change reports from the radio.  In that case only
4352ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            // the radio is the authority for the current state.
4362ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            final int length = mObservers.beginBroadcast();
4372ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            try {
4382ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                for (int i = 0; i < length; i++) {
4392ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    try {
4402ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                        mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(
4412ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                                Integer.toString(type), isActive, tsNanos);
4422ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    } catch (RemoteException e) {
4432ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    } catch (RuntimeException e) {
4442ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    }
4452ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                }
4462ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            } finally {
4472ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                mObservers.finishBroadcast();
4482ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            }
449db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai        }
45077b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
45177b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        boolean report = false;
45277b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        synchronized (mIdleTimerLock) {
45377b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            if (mActiveIdleTimers.isEmpty()) {
4542ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                // If there are no idle timers, we are not monitoring activity, so we
45577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                // are always considered active.
4562ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                isActive = true;
45777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            }
4582ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            if (mNetworkActive != isActive) {
4592ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                mNetworkActive = isActive;
4602ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                report = isActive;
46177b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            }
46277b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        }
46377b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        if (report) {
46477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            reportNetworkActive();
46577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        }
466db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai    }
467db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai
468db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai    /**
469b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey     * Prepare native daemon once connected, enabling modules and pushing any
470b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey     * existing in-memory rules.
471e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt     */
472b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey    private void prepareNativeDaemon() {
473b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        mBandwidthControlEnabled = false;
474b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey
475b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        // only enable bandwidth control when support exists
476b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        final boolean hasKernelSupport = new File("/proc/net/xt_qtaguid/ctrl").exists();
477b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        if (hasKernelSupport) {
478b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            Slog.d(TAG, "enabling bandwidth control");
479b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            try {
480b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mConnector.execute("bandwidth", "enable");
481b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mBandwidthControlEnabled = true;
482b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            } catch (NativeDaemonConnectorException e) {
483b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                Log.wtf(TAG, "problem enabling bandwidth controls", e);
484b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            }
485b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        } else {
486b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            Slog.d(TAG, "not enabling bandwidth control");
487b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        }
488b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey
489b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0");
490e5c3afb29241fd3faae309f973645d7f6a7ed111Robert Greenwalt
4917a1c3fce478122b9f03464117dc94d44f7c1995eJeff Sharkey        if (mBandwidthControlEnabled) {
4927a1c3fce478122b9f03464117dc94d44f7c1995eJeff Sharkey            try {
493e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn                getBatteryStats().noteNetworkStatsEnabled();
4947a1c3fce478122b9f03464117dc94d44f7c1995eJeff Sharkey            } catch (RemoteException e) {
4957a1c3fce478122b9f03464117dc94d44f7c1995eJeff Sharkey            }
4967a1c3fce478122b9f03464117dc94d44f7c1995eJeff Sharkey        }
4977a1c3fce478122b9f03464117dc94d44f7c1995eJeff Sharkey
498b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        // push any existing quota or UID rules
499b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        synchronized (mQuotaLock) {
500b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            int size = mActiveQuotas.size();
501b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            if (size > 0) {
502b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                Slog.d(TAG, "pushing " + size + " active quota rules");
503b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                final HashMap<String, Long> activeQuotas = mActiveQuotas;
504b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mActiveQuotas = Maps.newHashMap();
505b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) {
506b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                    setInterfaceQuota(entry.getKey(), entry.getValue());
507b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                }
508b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            }
509b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey
510b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            size = mActiveAlerts.size();
511b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            if (size > 0) {
512b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                Slog.d(TAG, "pushing " + size + " active alert rules");
513b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                final HashMap<String, Long> activeAlerts = mActiveAlerts;
514b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mActiveAlerts = Maps.newHashMap();
515b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) {
516b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                    setInterfaceAlert(entry.getKey(), entry.getValue());
517b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                }
518b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            }
519b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey
520b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            size = mUidRejectOnQuota.size();
521b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            if (size > 0) {
522b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                Slog.d(TAG, "pushing " + size + " active uid rules");
523b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                final SparseBooleanArray uidRejectOnQuota = mUidRejectOnQuota;
524b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mUidRejectOnQuota = new SparseBooleanArray();
525b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                for (int i = 0; i < uidRejectOnQuota.size(); i++) {
526b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                    setUidNetworkRules(uidRejectOnQuota.keyAt(i), uidRejectOnQuota.valueAt(i));
527b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                }
528b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            }
529b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        }
530c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey
531c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        // TODO: Push any existing firewall state
53269ddab4575ff684c533c995e07ca15fe18543fc0Jeff Sharkey        setFirewallEnabled(mFirewallEnabled || LockdownVpnTracker.isEnabled());
533b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey    }
5344d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat
5355c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti    /**
5365c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti     * Notify our observers of a new or updated interface address.
5375c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti     */
53864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti    private void notifyAddressUpdated(String iface, LinkAddress address) {
5395c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti        final int length = mObservers.beginBroadcast();
5402c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        try {
5412c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            for (int i = 0; i < length; i++) {
5422c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
5432c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                    mObservers.getBroadcastItem(i).addressUpdated(iface, address);
5442c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
5452c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RuntimeException e) {
5462c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
5475c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti            }
5482c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        } finally {
5492c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            mObservers.finishBroadcast();
5505c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti        }
5515c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti    }
5525c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti
5535c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti    /**
5545c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti     * Notify our observers of a deleted interface address.
5555c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti     */
55664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti    private void notifyAddressRemoved(String iface, LinkAddress address) {
5575c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti        final int length = mObservers.beginBroadcast();
5582c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        try {
5592c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            for (int i = 0; i < length; i++) {
5602c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
5612c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                    mObservers.getBroadcastItem(i).addressRemoved(iface, address);
5622c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
5632c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RuntimeException e) {
5642c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
5655c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti            }
5662c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        } finally {
5672c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            mObservers.finishBroadcast();
5685c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti        }
5695c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti    }
5705c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti
5715ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti    /**
5725ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti     * Notify our observers of DNS server information received.
5735ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti     */
5745ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti    private void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
5755ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        final int length = mObservers.beginBroadcast();
5762c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        try {
5772c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            for (int i = 0; i < length; i++) {
5782c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
5792c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                    mObservers.getBroadcastItem(i).interfaceDnsServerInfo(iface, lifetime,
5802c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                        addresses);
5812c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
5822c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RuntimeException e) {
5832c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
5845ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti            }
5852c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        } finally {
5862c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            mObservers.finishBroadcast();
5875ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        }
5885ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti    }
5895ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
590c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    /**
591c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti     * Notify our observers of a route change.
592c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti     */
593c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    private void notifyRouteChange(String action, RouteInfo route) {
594c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        final int length = mObservers.beginBroadcast();
595c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        try {
596c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            for (int i = 0; i < length; i++) {
597c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                try {
598c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    if (action.equals("updated")) {
599c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                        mObservers.getBroadcastItem(i).routeUpdated(route);
600c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    } else {
601c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                        mObservers.getBroadcastItem(i).routeRemoved(route);
602c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    }
603c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                } catch (RemoteException e) {
604c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                } catch (RuntimeException e) {
605c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                }
606c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            }
607c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        } finally {
608c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            mObservers.finishBroadcast();
609c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        }
610c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    }
611c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti
612873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    //
613873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    // Netd Callback handling
614873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    //
615873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
616b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey    private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks {
617b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        @Override
618873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        public void onDaemonConnected() {
619b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            // event is dispatched from internal NDC thread, so we prepare the
620b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            // daemon back on main thread.
621b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            if (mConnectedSignal != null) {
622b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mConnectedSignal.countDown();
623b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mConnectedSignal = null;
624b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            } else {
6252c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                mFgHandler.post(new Runnable() {
626b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                    @Override
627b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                    public void run() {
628b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                        prepareNativeDaemon();
629b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                    }
630b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                });
631b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            }
632873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        }
633fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey
634b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        @Override
63577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        public boolean onCheckHoldWakeLock(int code) {
63677b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            return code == NetdResponseCode.InterfaceClassActivity;
63777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        }
63877b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
63977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        @Override
640873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        public boolean onEvent(int code, String raw, String[] cooked) {
641a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti            String errorMessage = String.format("Invalid event from daemon (%s)", raw);
64212b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall            switch (code) {
64312b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall            case NetdResponseCode.InterfaceChange:
64412b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    /*
64512b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                     * a network interface change occured
64612b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                     * Format: "NNN Iface added <name>"
64712b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                     *         "NNN Iface removed <name>"
64812b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                     *         "NNN Iface changed <name> <up/down>"
64912b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                     *         "NNN Iface linkstatus <name> <up/down>"
65012b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                     */
65112b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    if (cooked.length < 4 || !cooked[1].equals("Iface")) {
652a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti                        throw new IllegalStateException(errorMessage);
65312b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    }
65412b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    if (cooked[2].equals("added")) {
65512b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        notifyInterfaceAdded(cooked[3]);
65612b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        return true;
65712b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    } else if (cooked[2].equals("removed")) {
65812b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        notifyInterfaceRemoved(cooked[3]);
65912b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        return true;
66012b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    } else if (cooked[2].equals("changed") && cooked.length == 5) {
66112b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up"));
66212b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        return true;
66312b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    } else if (cooked[2].equals("linkstate") && cooked.length == 5) {
66412b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
66512b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        return true;
66612b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    }
667a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti                    throw new IllegalStateException(errorMessage);
66812b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    // break;
66912b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall            case NetdResponseCode.BandwidthControl:
67012b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    /*
67112b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                     * Bandwidth control needs some attention
67212b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                     * Format: "NNN limit alert <alertName> <ifaceName>"
67312b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                     */
67412b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    if (cooked.length < 5 || !cooked[1].equals("limit")) {
675a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti                        throw new IllegalStateException(errorMessage);
67612b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    }
67712b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    if (cooked[2].equals("alert")) {
67812b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        notifyLimitReached(cooked[3], cooked[4]);
67912b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                        return true;
68012b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    }
681a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti                    throw new IllegalStateException(errorMessage);
68212b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall                    // break;
683db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai            case NetdResponseCode.InterfaceClassActivity:
684db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai                    /*
685db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai                     * An network interface class state changed (active/idle)
686db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai                     * Format: "NNN IfaceClass <active/idle> <label>"
687db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai                     */
688db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai                    if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) {
689a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti                        throw new IllegalStateException(errorMessage);
690db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai                    }
6910535a9f7aa5d0f875b06845e9af5f6dbfc5c8a19Ashish Sharma                    long timestampNanos = 0;
6920535a9f7aa5d0f875b06845e9af5f6dbfc5c8a19Ashish Sharma                    if (cooked.length == 5) {
6930535a9f7aa5d0f875b06845e9af5f6dbfc5c8a19Ashish Sharma                        try {
6940535a9f7aa5d0f875b06845e9af5f6dbfc5c8a19Ashish Sharma                            timestampNanos = Long.parseLong(cooked[4]);
6950535a9f7aa5d0f875b06845e9af5f6dbfc5c8a19Ashish Sharma                        } catch(NumberFormatException ne) {}
6962ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    } else {
6972ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                        timestampNanos = SystemClock.elapsedRealtimeNanos();
6980535a9f7aa5d0f875b06845e9af5f6dbfc5c8a19Ashish Sharma                    }
699db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai                    boolean isActive = cooked[2].equals("active");
7000535a9f7aa5d0f875b06845e9af5f6dbfc5c8a19Ashish Sharma                    notifyInterfaceClassActivity(Integer.parseInt(cooked[3]),
7012ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                            isActive ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
7022ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                            : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW, timestampNanos, false);
703db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai                    return true;
704db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai                    // break;
7055c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti            case NetdResponseCode.InterfaceAddressChange:
7065c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                    /*
7075c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                     * A network address change occurred
7085c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                     * Format: "NNN Address updated <addr> <iface> <flags> <scope>"
7095c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                     *         "NNN Address removed <addr> <iface> <flags> <scope>"
7105c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                     */
711a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti                    if (cooked.length < 7 || !cooked[1].equals("Address")) {
712a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti                        throw new IllegalStateException(errorMessage);
7135c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                    }
7145c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti
71564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti                    String iface = cooked[4];
7165ad421a3d00c92c155d57af9d1a05d81cc2fa88fLorenzo Colitti                    LinkAddress address;
7175c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                    try {
71864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti                        int flags = Integer.parseInt(cooked[5]);
71964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti                        int scope = Integer.parseInt(cooked[6]);
72064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti                        address = new LinkAddress(cooked[3], flags, scope);
7215ad421a3d00c92c155d57af9d1a05d81cc2fa88fLorenzo Colitti                    } catch(NumberFormatException e) {     // Non-numeric lifetime or scope.
7225ad421a3d00c92c155d57af9d1a05d81cc2fa88fLorenzo Colitti                        throw new IllegalStateException(errorMessage, e);
72364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti                    } catch(IllegalArgumentException e) {  // Malformed/invalid IP address.
7245ad421a3d00c92c155d57af9d1a05d81cc2fa88fLorenzo Colitti                        throw new IllegalStateException(errorMessage, e);
7255c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                    }
7265c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti
7275c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                    if (cooked[2].equals("updated")) {
72864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti                        notifyAddressUpdated(iface, address);
7295c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                    } else {
73064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti                        notifyAddressRemoved(iface, address);
7315c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                    }
7325c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                    return true;
7335c7daac2e3d9020185699ba554d763b825ab1778Lorenzo Colitti                    // break;
7345ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti            case NetdResponseCode.InterfaceDnsServerInfo:
7355ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                    /*
7365ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                     * Information about available DNS servers has been received.
7375ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                     * Format: "NNN DnsInfo servers <interface> <lifetime> <servers>"
7385ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                     */
7395ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                    long lifetime;  // Actually a 32-bit unsigned integer.
7405ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
7415ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                    if (cooked.length == 6 &&
7425ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                        cooked[1].equals("DnsInfo") &&
7435ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                        cooked[2].equals("servers")) {
7445ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                        try {
7455ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                            lifetime = Long.parseLong(cooked[4]);
7465ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                        } catch (NumberFormatException e) {
7475ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                            throw new IllegalStateException(errorMessage);
7485ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                        }
7495ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                        String[] servers = cooked[5].split(",");
7505ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                        notifyInterfaceDnsServerInfo(cooked[3], lifetime, servers);
7515ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                    }
7525ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                    return true;
7535ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                    // break;
754c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            case NetdResponseCode.RouteChange:
755c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    /*
756c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                     * A route has been updated or removed.
757c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                     * Format: "NNN Route <updated|removed> <dst> [via <gateway] [dev <iface>]"
758c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                     */
759c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    if (!cooked[1].equals("Route") || cooked.length < 6) {
760c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                        throw new IllegalStateException(errorMessage);
761c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    }
762c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti
763c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    String via = null;
764c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    String dev = null;
765c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    boolean valid = true;
766c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    for (int i = 4; (i + 1) < cooked.length && valid; i += 2) {
767c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                        if (cooked[i].equals("dev")) {
768c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            if (dev == null) {
769c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                                dev = cooked[i+1];
770c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            } else {
771c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                                valid = false;  // Duplicate interface.
772c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            }
773c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                        } else if (cooked[i].equals("via")) {
774c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            if (via == null) {
775c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                                via = cooked[i+1];
776c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            } else {
777c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                                valid = false;  // Duplicate gateway.
778c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            }
779c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                        } else {
780c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            valid = false;      // Unknown syntax.
781c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                        }
782c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    }
783c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    if (valid) {
784c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                        try {
785c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            // InetAddress.parseNumericAddress(null) inexplicably returns ::1.
786c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            InetAddress gateway = null;
787c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            if (via != null) gateway = InetAddress.parseNumericAddress(via);
788c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            RouteInfo route = new RouteInfo(new IpPrefix(cooked[3]), gateway, dev);
789c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            notifyRouteChange(cooked[2], route);
790c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                            return true;
791c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                        } catch (IllegalArgumentException e) {}
792c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    }
793c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    throw new IllegalStateException(errorMessage);
794c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                    // break;
79512b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall            default: break;
796e325392c257a5460de6327420c81729f4e687881Robert Greenwalt            }
797e325392c257a5460de6327420c81729f4e687881Robert Greenwalt            return false;
798873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        }
799873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
800873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
801ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat
802873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    //
803873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    // INetworkManagementService members
804873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    //
805873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
806af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
807af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public String[] listInterfaces() {
8084529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
809a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
810ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            return NativeDaemonEvent.filterMessageList(
811ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                    mConnector.executeForList("interface", "list"), InterfaceListResult);
812a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
813276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
814a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
815ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat    }
816ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat
817af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
818af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public InterfaceConfiguration getInterfaceConfig(String iface) {
8194529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
820ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
821ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        final NativeDaemonEvent event;
822a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
823ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            event = mConnector.execute("interface", "getcfg", iface);
824a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
825276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
826a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
827ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat
828ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        event.checkCode(InterfaceGetCfgResult);
829ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
830ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz flag1 flag2 flag3
831ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        final StringTokenizer st = new StringTokenizer(event.getMessage());
832ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat
833a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        InterfaceConfiguration cfg;
834ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat        try {
835a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            cfg = new InterfaceConfiguration();
836ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            cfg.setHardwareAddress(st.nextToken(" "));
837ed1264093234b1f1354cd5f669eb82a50bb56869Robert Greenwalt            InetAddress addr = null;
8382d2afd13af94c2669eb464101dee3b17c8448110Robert Greenwalt            int prefixLength = 0;
839a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            try {
840ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                addr = NetworkUtils.numericToInetAddress(st.nextToken());
841e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt            } catch (IllegalArgumentException iae) {
842e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt                Slog.e(TAG, "Failed to parse ipaddr", iae);
843a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            }
844ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat
845a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            try {
846ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                prefixLength = Integer.parseInt(st.nextToken());
8472d2afd13af94c2669eb464101dee3b17c8448110Robert Greenwalt            } catch (NumberFormatException nfe) {
8482d2afd13af94c2669eb464101dee3b17c8448110Robert Greenwalt                Slog.e(TAG, "Failed to parse prefixLength", nfe);
849a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            }
85004808c294027f8bc318643a94c85a999257d7f52Robert Greenwalt
851ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            cfg.setLinkAddress(new LinkAddress(addr, prefixLength));
852ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            while (st.hasMoreTokens()) {
853ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey                cfg.setFlag(st.nextToken());
854ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey            }
855a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NoSuchElementException nsee) {
856ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            throw new IllegalStateException("Invalid response from daemon: " + event);
857ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat        }
858ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat        return cfg;
859ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat    }
860ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat
861af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
862af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {
8634529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
864ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey        LinkAddress linkAddr = cfg.getLinkAddress();
8652d2afd13af94c2669eb464101dee3b17c8448110Robert Greenwalt        if (linkAddr == null || linkAddr.getAddress() == null) {
8662d2afd13af94c2669eb464101dee3b17c8448110Robert Greenwalt            throw new IllegalStateException("Null LinkAddress given");
867ed1264093234b1f1354cd5f669eb82a50bb56869Robert Greenwalt        }
868ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
869ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        final Command cmd = new Command("interface", "setcfg", iface,
8702d2afd13af94c2669eb464101dee3b17c8448110Robert Greenwalt                linkAddr.getAddress().getHostAddress(),
8717dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti                linkAddr.getPrefixLength());
872ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        for (String flag : cfg.getFlags()) {
873ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            cmd.appendArg(flag);
874ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        }
875ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
876a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
877ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute(cmd);
878a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
879276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
880a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
881873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
882873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
883af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
884af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void setInterfaceDown(String iface) {
8854529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
88631c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
887ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey        ifcg.setInterfaceDown();
88831c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        setInterfaceConfig(iface, ifcg);
8897244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff    }
8907244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff
891af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
892af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void setInterfaceUp(String iface) {
8934529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
89431c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
895ddba10622dfd3122cf99c795706754e0d41858c3Jeff Sharkey        ifcg.setInterfaceUp();
89631c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        setInterfaceConfig(iface, ifcg);
8977244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff    }
8987244c977ecbc1f73e4cfd9d824fc2b68aa886139Irfan Sheriff
899af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
900af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) {
9014529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
9027329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff        try {
903ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute(
904ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                    "interface", "ipv6privacyextensions", iface, enable ? "enable" : "disable");
9057329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff        } catch (NativeDaemonConnectorException e) {
906276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
9077329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff        }
9087329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff    }
9097329361cdce711775542b112663bf71a6e0d5cefIrfan Sheriff
910f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff    /* TODO: This is right now a IPv4 only function. Works for wifi which loses its
911f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff       IPv6 addresses on interface down, but we need to do full clean up here */
912af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
913af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void clearInterfaceAddresses(String iface) {
9144529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
915f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff        try {
916ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("interface", "clearaddrs", iface);
917f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff        } catch (NativeDaemonConnectorException e) {
918276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
919f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff        }
920f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff    }
921f5600618df153d9c51388562ebf3524e3bdc8b7dIrfan Sheriff
922af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
923af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void enableIpv6(String iface) {
9244529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
9257960d9f888e31602e17b8856c77a3826bf8c841erepo sync        try {
926ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("interface", "ipv6", iface, "enable");
9277960d9f888e31602e17b8856c77a3826bf8c841erepo sync        } catch (NativeDaemonConnectorException e) {
928276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
9297960d9f888e31602e17b8856c77a3826bf8c841erepo sync        }
9307960d9f888e31602e17b8856c77a3826bf8c841erepo sync    }
9317960d9f888e31602e17b8856c77a3826bf8c841erepo sync
932af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
933af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void disableIpv6(String iface) {
9344529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
9357960d9f888e31602e17b8856c77a3826bf8c841erepo sync        try {
936ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("interface", "ipv6", iface, "disable");
9377960d9f888e31602e17b8856c77a3826bf8c841erepo sync        } catch (NativeDaemonConnectorException e) {
938276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
9397960d9f888e31602e17b8856c77a3826bf8c841erepo sync        }
9407960d9f888e31602e17b8856c77a3826bf8c841erepo sync    }
9417960d9f888e31602e17b8856c77a3826bf8c841erepo sync
942af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
943e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti    public void setInterfaceIpv6NdOffload(String iface, boolean enable) {
944e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
945e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti        try {
946e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti            mConnector.execute(
947e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti                    "interface", "ipv6ndoffload", iface, (enable ? "enable" : "disable"));
948e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti        } catch (NativeDaemonConnectorException e) {
949e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti            throw e.rethrowAsParcelableException();
950e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti        }
951e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti    }
952e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti
953e21a26b3ba78b0238f4ed4a09b43319a2320fbaaLorenzo Colitti    @Override
954b2829fa165124264c7ec06a6e23b08a1d97b99e5Sreeram Ramachandran    public void addRoute(int netId, RouteInfo route) {
955a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        modifyRoute("add", "" + netId, route);
95659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
95759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
958af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
959b2829fa165124264c7ec06a6e23b08a1d97b99e5Sreeram Ramachandran    public void removeRoute(int netId, RouteInfo route) {
960a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        modifyRoute("remove", "" + netId, route);
9613b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt    }
9623b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt
963a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    private void modifyRoute(String action, String netId, RouteInfo route) {
9644529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
9653b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt
966b2829fa165124264c7ec06a6e23b08a1d97b99e5Sreeram Ramachandran        final Command cmd = new Command("network", "route", action, netId);
96759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
968b2829fa165124264c7ec06a6e23b08a1d97b99e5Sreeram Ramachandran        // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
969b2829fa165124264c7ec06a6e23b08a1d97b99e5Sreeram Ramachandran        cmd.appendArg(route.getInterface());
9704b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti        cmd.appendArg(route.getDestination().toString());
9714b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti
9724b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti        switch (route.getType()) {
9734b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti            case RouteInfo.RTN_UNICAST:
9744b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti                if (route.hasGateway()) {
9754b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti                    cmd.appendArg(route.getGateway().getHostAddress());
9764b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti                }
9774b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti                break;
9784b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti            case RouteInfo.RTN_UNREACHABLE:
9794b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti                cmd.appendArg("unreachable");
9804b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti                break;
9814b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti            case RouteInfo.RTN_THROW:
9824b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti                cmd.appendArg("throw");
9834b0f8e6fb707e19799011c1f4a5e4f54603e34b1Lorenzo Colitti                break;
9841fbcb2719828f16aec8b2d742a20b98e4a2cf17cSreeram Ramachandran        }
985ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
98659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        try {
987ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute(cmd);
98859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        } catch (NativeDaemonConnectorException e) {
989276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
99059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        }
99159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
99259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
99359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    private ArrayList<String> readRouteList(String filename) {
99459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        FileInputStream fstream = null;
99559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        ArrayList<String> list = new ArrayList<String>();
99659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
99759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        try {
99859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            fstream = new FileInputStream(filename);
99959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            DataInputStream in = new DataInputStream(fstream);
100059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            BufferedReader br = new BufferedReader(new InputStreamReader(in));
100159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            String s;
100259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
100359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            // throw away the title line
100459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
100559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            while (((s = br.readLine()) != null) && (s.length() != 0)) {
100659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                list.add(s);
100759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            }
100859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        } catch (IOException ex) {
100959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            // return current list, possibly empty
101059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        } finally {
101159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            if (fstream != null) {
101259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                try {
101359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    fstream.close();
101459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                } catch (IOException ex) {}
101559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            }
101659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        }
101759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
101859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        return list;
101959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
102059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
1021af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
102259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    public RouteInfo[] getRoutes(String interfaceName) {
10234529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
102459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
102559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
102659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        // v4 routes listed as:
102759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        // iface dest-addr gateway-addr flags refcnt use metric netmask mtu window IRTT
102859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        for (String s : readRouteList("/proc/net/route")) {
102959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            String[] fields = s.split("\t");
103059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
103159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            if (fields.length > 7) {
103259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                String iface = fields[0];
103359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
103459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                if (interfaceName.equals(iface)) {
103559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    String dest = fields[1];
103659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    String gate = fields[2];
103759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    String flags = fields[3]; // future use?
103859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    String mask = fields[7];
103959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    try {
104059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        // address stored as a hex string, ex: 0014A8C0
104159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        InetAddress destAddr =
104259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                                NetworkUtils.intToInetAddress((int)Long.parseLong(dest, 16));
104359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        int prefixLength =
104459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                                NetworkUtils.netmaskIntToPrefixLength(
104559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                                (int)Long.parseLong(mask, 16));
104659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        LinkAddress linkAddress = new LinkAddress(destAddr, prefixLength);
104759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
104859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        // address stored as a hex string, ex 0014A8C0
104959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        InetAddress gatewayAddr =
105059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                                NetworkUtils.intToInetAddress((int)Long.parseLong(gate, 16));
105159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
10527b5fd05d4e41c91386974970e3da5dcbfc2b2132Wink Saville                        RouteInfo route = new RouteInfo(linkAddress, gatewayAddr);
105359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        routes.add(route);
105459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    } catch (Exception e) {
105559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        Log.e(TAG, "Error parsing route " + s + " : " + e);
105659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        continue;
105759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    }
105859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                }
105959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            }
106059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        }
106159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
106259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        // v6 routes listed as:
106359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        // dest-addr prefixlength ?? ?? gateway-addr ?? ?? ?? ?? iface
106459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        for (String s : readRouteList("/proc/net/ipv6_route")) {
106559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            String[]fields = s.split("\\s+");
106659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            if (fields.length > 9) {
106759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                String iface = fields[9].trim();
106859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                if (interfaceName.equals(iface)) {
106959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    String dest = fields[0];
107059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    String prefix = fields[1];
107159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    String gate = fields[4];
107259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
107359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    try {
107459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        // prefix length stored as a hex string, ex 40
107559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        int prefixLength = Integer.parseInt(prefix, 16);
107659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
107759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        // address stored as a 32 char hex string
107859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        // ex fe800000000000000000000000000000
107959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        InetAddress destAddr = NetworkUtils.hexToInet6Address(dest);
108059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        LinkAddress linkAddress = new LinkAddress(destAddr, prefixLength);
108159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
108259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        InetAddress gateAddr = NetworkUtils.hexToInet6Address(gate);
108359b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
10847b5fd05d4e41c91386974970e3da5dcbfc2b2132Wink Saville                        RouteInfo route = new RouteInfo(linkAddress, gateAddr);
108559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        routes.add(route);
108659b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    } catch (Exception e) {
108759b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        Log.e(TAG, "Error parsing route " + s + " : " + e);
108859b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                        continue;
108959b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                    }
109059b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt                }
109159b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt            }
109259b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt        }
1093ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        return routes.toArray(new RouteInfo[routes.size()]);
109459b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt    }
109559b1a4ede7032c1b4d897e13dd4ede09b5e14743Robert Greenwalt
1096af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
10979d9b74a900696191048aa97cc3c854072640428bsy.yun    public void setMtu(String iface, int mtu) {
10989d9b74a900696191048aa97cc3c854072640428bsy.yun        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
10999d9b74a900696191048aa97cc3c854072640428bsy.yun
11009d9b74a900696191048aa97cc3c854072640428bsy.yun        final NativeDaemonEvent event;
11019d9b74a900696191048aa97cc3c854072640428bsy.yun        try {
11029d9b74a900696191048aa97cc3c854072640428bsy.yun            event = mConnector.execute("interface", "setmtu", iface, mtu);
11039d9b74a900696191048aa97cc3c854072640428bsy.yun        } catch (NativeDaemonConnectorException e) {
11049d9b74a900696191048aa97cc3c854072640428bsy.yun            throw e.rethrowAsParcelableException();
11059d9b74a900696191048aa97cc3c854072640428bsy.yun        }
11069d9b74a900696191048aa97cc3c854072640428bsy.yun    }
11079d9b74a900696191048aa97cc3c854072640428bsy.yun
11089d9b74a900696191048aa97cc3c854072640428bsy.yun    @Override
1109873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    public void shutdown() {
1110af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey        // TODO: remove from aidl if nobody calls externally
1111af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey        mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
1112873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
11138a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        Slog.d(TAG, "Shutting down");
1114873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1115873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1116af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1117873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    public boolean getIpForwardingEnabled() throws IllegalStateException{
11184529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1119873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1120ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        final NativeDaemonEvent event;
1121a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1122ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            event = mConnector.execute("ipfwd", "status");
1123a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1124276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1125a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1126873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1127ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        // 211 Forwarding enabled
1128ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        event.checkCode(IpFwdStatusResult);
1129ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        return event.getMessage().endsWith("enabled");
1130873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1131873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1132af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1133af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void setIpForwardingEnabled(boolean enable) {
11344529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
113531c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        try {
1136ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("ipfwd", enable ? "enable" : "disable");
113731c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        } catch (NativeDaemonConnectorException e) {
1138276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
113931c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        }
1140873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1141873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1142af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1143af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void startTethering(String[] dhcpRange) {
11444529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1145bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt        // cmd is "tether start first_start first_stop second_start second_stop ..."
1146bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt        // an odd number of addrs will fail
1147ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
1148ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        final Command cmd = new Command("tether", "start");
1149bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt        for (String d : dhcpRange) {
1150ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            cmd.appendArg(d);
1151bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt        }
1152a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root
1153a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1154ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute(cmd);
1155a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1156276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1157a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1158873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1159873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1160af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1161af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void stopTethering() {
11624529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1163a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1164ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("tether", "stop");
1165a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1166276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1167a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1168873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1169873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1170af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1171af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public boolean isTetheringStarted() {
11724529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1173873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1174ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        final NativeDaemonEvent event;
1175a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1176ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            event = mConnector.execute("tether", "status");
1177a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1178276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1179a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1180873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1181ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        // 210 Tethering services started
1182ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        event.checkCode(TetherStatusResult);
1183ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        return event.getMessage().endsWith("started");
1184873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1185fe19f1234e460a22e43a53665db1c48613844fa6Matthew Xie
1186af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1187af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void tetherInterface(String iface) {
11884529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1189a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1190ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("tether", "interface", "add", iface);
1191a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1192276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1193a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1194a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        List<RouteInfo> routes = new ArrayList<RouteInfo>();
1195a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        // The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it
1196a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        // suitable to use as a route destination.
1197a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        routes.add(new RouteInfo(getInterfaceConfig(iface).getLinkAddress(), null, iface));
1198a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        addInterfaceToLocalNetwork(iface, routes);
1199873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1200873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1201af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1202873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    public void untetherInterface(String iface) {
12034529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1204a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1205ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("tether", "interface", "remove", iface);
1206a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1207276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1208a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1209a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        removeInterfaceFromLocalNetwork(iface);
1210873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1211873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1212af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1213af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public String[] listTetheredInterfaces() {
12144529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1215a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1216ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            return NativeDaemonEvent.filterMessageList(
1217ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                    mConnector.executeForList("tether", "interface", "list"),
1218ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                    TetherInterfaceListResult);
1219a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1220276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1221a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1222873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1223873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1224af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1225b57edc5ae999abd9c7310833f4f10bbacbc469d7Lorenzo Colitti    public void setDnsForwarders(Network network, String[] dns) {
12264529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1227ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
1228b57edc5ae999abd9c7310833f4f10bbacbc469d7Lorenzo Colitti        int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
1229b57edc5ae999abd9c7310833f4f10bbacbc469d7Lorenzo Colitti        final Command cmd = new Command("tether", "dns", "set", netId);
1230b57edc5ae999abd9c7310833f4f10bbacbc469d7Lorenzo Colitti
1231ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        for (String s : dns) {
1232ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress());
1233ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        }
1234ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
1235873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        try {
1236ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute(cmd);
1237ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        } catch (NativeDaemonConnectorException e) {
1238ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            throw e.rethrowAsParcelableException();
1239873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat        }
1240873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1241873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1242af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1243af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public String[] getDnsForwarders() {
12444529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1245a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1246ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            return NativeDaemonEvent.filterMessageList(
1247ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                    mConnector.executeForList("tether", "dns", "list"), TetherDnsFwdTgtListResult);
1248a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1249276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1250a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1251873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1252873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
12531da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo    private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) {
12541da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo        ArrayList<InterfaceAddress> filtered = new ArrayList<InterfaceAddress>(addresses.size());
12551da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo        for (InterfaceAddress ia : addresses) {
12561da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo            if (!ia.getAddress().isLinkLocalAddress())
12571da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo                filtered.add(ia);
12581da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo        }
12591da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo        return filtered;
12601da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo    }
12611da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo
1262ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey    private void modifyNat(String action, String internalInterface, String externalInterface)
12633b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            throws SocketException {
1264ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        final Command cmd = new Command("nat", action, internalInterface, externalInterface);
12653b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt
1266ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        final NetworkInterface internalNetworkInterface = NetworkInterface.getByName(
1267ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                internalInterface);
1268e83d181606981bcacd78e55b293fe9fa95b2551dRobert Greenwalt        if (internalNetworkInterface == null) {
1269ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            cmd.appendArg("0");
1270e83d181606981bcacd78e55b293fe9fa95b2551dRobert Greenwalt        } else {
12711da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo            // Don't touch link-local routes, as link-local addresses aren't routable,
12721da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo            // kernel creates link-local routes on all interfaces automatically
12731da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo            List<InterfaceAddress> interfaceAddresses = excludeLinkLocal(
12741da35f71d2889699864d0cd8f76a6ee8caacfb5bjiaguo                    internalNetworkInterface.getInterfaceAddresses());
1275ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            cmd.appendArg(interfaceAddresses.size());
1276e83d181606981bcacd78e55b293fe9fa95b2551dRobert Greenwalt            for (InterfaceAddress ia : interfaceAddresses) {
1277ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                InetAddress addr = NetworkUtils.getNetworkPart(
1278ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                        ia.getAddress(), ia.getNetworkPrefixLength());
1279ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                cmd.appendArg(addr.getHostAddress() + "/" + ia.getNetworkPrefixLength());
1280e83d181606981bcacd78e55b293fe9fa95b2551dRobert Greenwalt            }
12813b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt        }
12823b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt
128331c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        try {
1284ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute(cmd);
128531c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        } catch (NativeDaemonConnectorException e) {
1286276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
128731c6e4817f6c967fc4f61c4f1d9f25743958f7deJeff Sharkey        }
12883b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt    }
12893b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt
1290af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1291af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void enableNat(String internalInterface, String externalInterface) {
12924529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1293a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
12943b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            modifyNat("enable", internalInterface, externalInterface);
1295ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        } catch (SocketException e) {
1296ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            throw new IllegalStateException(e);
1297a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1298873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
1299873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat
1300af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1301af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void disableNat(String internalInterface, String externalInterface) {
13024529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1303a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
13043b28e9a3daede9eac44faeb736ab4c8386ddd089Robert Greenwalt            modifyNat("disable", internalInterface, externalInterface);
1305ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        } catch (SocketException e) {
1306ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            throw new IllegalStateException(e);
1307a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
1308873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat    }
130972759df749bb8557269db86c2e3b2a8a0343cc26San Mehat
1310af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1311af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public String[] listTtys() {
13124529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1313a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1314ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            return NativeDaemonEvent.filterMessageList(
1315ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                    mConnector.executeForList("list_ttys"), TtyListResult);
1316a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1317276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1318a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
131972759df749bb8557269db86c2e3b2a8a0343cc26San Mehat    }
132072759df749bb8557269db86c2e3b2a8a0343cc26San Mehat
1321af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1322af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void attachPppd(
1323af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey            String tty, String localAddr, String remoteAddr, String dns1Addr, String dns2Addr) {
13244529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
132572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat        try {
1326ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("pppd", "attach", tty,
1327e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt                    NetworkUtils.numericToInetAddress(localAddr).getHostAddress(),
1328e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt                    NetworkUtils.numericToInetAddress(remoteAddr).getHostAddress(),
1329e590373ea71251cfffc8f22f011e2e6335dce716Robert Greenwalt                    NetworkUtils.numericToInetAddress(dns1Addr).getHostAddress(),
1330ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                    NetworkUtils.numericToInetAddress(dns2Addr).getHostAddress());
1331a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1332276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
133372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat        }
133472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat    }
133572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat
1336af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1337af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void detachPppd(String tty) {
13384529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1339a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1340ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("pppd", "detach", tty);
1341a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1342276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1343a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
134472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat    }
1345ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt
1346af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1347af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void startAccessPoint(
134890542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff            WifiConfiguration wifiConfig, String wlanIface) {
13494529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1350a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1351cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff            wifiFirmwareReload(wlanIface, "AP");
1352a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            if (wifiConfig == null) {
135390542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff                mConnector.execute("softap", "set", wlanIface);
1354a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            } else {
135590542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff                mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
135628dd15b2d48752f8ea86d1fe10e31da3eeba5bb0Dmitry Shmidt                                   "broadcast", "6", getSecurityType(wifiConfig),
13573606254a507d838dbec0da35f88c432e6eef7643Kenny Root                                   new SensitiveArg(wifiConfig.preSharedKey));
1358a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            }
1359ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("softap", "startap");
1360a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1361276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1362a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
13635321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff    }
13645321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff
1365ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey    private static String getSecurityType(WifiConfiguration wifiConfig) {
1366ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff        switch (wifiConfig.getAuthType()) {
1367ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff            case KeyMgmt.WPA_PSK:
1368ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff                return "wpa-psk";
1369ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff            case KeyMgmt.WPA2_PSK:
1370ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff                return "wpa2-psk";
1371ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff            default:
1372ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff                return "open";
1373ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff        }
1374ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff    }
1375ec8d23af7372204f068aebaa1bfae87dc9260e23Irfan Sheriff
1376cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    /* @param mode can be "AP", "STA" or "P2P" */
1377af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1378af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void wifiFirmwareReload(String wlanIface, String mode) {
13794529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1380cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        try {
1381ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("softap", "fwreload", wlanIface, mode);
1382cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        } catch (NativeDaemonConnectorException e) {
1383276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1384cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff        }
1385cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff    }
1386cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff
1387af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
1388af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    public void stopAccessPoint(String wlanIface) {
13894529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1390a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1391ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("softap", "stopap");
1392cb30b22ff507a5a9a5d9c584f8b082f5e96c4d02Irfan Sheriff            wifiFirmwareReload(wlanIface, "STA");
1393a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1394276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1395a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        }
13965321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff    }
13975321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff
1398af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
139990542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff    public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface) {
14004529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1401a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        try {
1402a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            if (wifiConfig == null) {
140390542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff                mConnector.execute("softap", "set", wlanIface);
1404a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            } else {
140590542758d4fef2e5ff8badaf3b40c2a227fbfc47Irfan Sheriff                mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
140628dd15b2d48752f8ea86d1fe10e31da3eeba5bb0Dmitry Shmidt                                   "broadcast", "6", getSecurityType(wifiConfig),
14073606254a507d838dbec0da35f88c432e6eef7643Kenny Root                                   new SensitiveArg(wifiConfig.preSharedKey));
1408a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root            }
1409a80ce06d4c54e43243073f8ceff024f9dda7140eKenny Root        } catch (NativeDaemonConnectorException e) {
1410276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1411c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff        }
1412c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff    }
141391cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat
1414eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey    @Override
141577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    public void addIdleTimer(String iface, int timeout, final int type) {
14160412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
14170412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
14180412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        if (DBG) Slog.d(TAG, "Adding idletimer");
14190412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
14200412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        synchronized (mIdleTimerLock) {
14210412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            IdleTimerParams params = mActiveIdleTimers.get(iface);
14220412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            if (params != null) {
14230412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                // the interface already has idletimer, update network count
14240412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                params.networkCount++;
14250412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                return;
14260412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            }
14270412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
14280412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            try {
142977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                mConnector.execute("idletimer", "add", iface, Integer.toString(timeout),
143077b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                        Integer.toString(type));
14310412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            } catch (NativeDaemonConnectorException e) {
14320412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                throw e.rethrowAsParcelableException();
14330412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            }
143477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
143577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
1436e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn            // Networks start up.
143777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            if (ConnectivityManager.isNetworkTypeMobile(type)) {
143877b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                mNetworkActive = false;
143977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            }
14402ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            mDaemonHandler.post(new Runnable() {
144177b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                @Override public void run() {
14422ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    notifyInterfaceClassActivity(type,
14432ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                            DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH,
14442ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                            SystemClock.elapsedRealtimeNanos(), false);
144577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                }
144677b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            });
14470412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        }
14480412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    }
14490412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
14500412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    @Override
14510412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    public void removeIdleTimer(String iface) {
14520412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
14530412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
14540412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        if (DBG) Slog.d(TAG, "Removing idletimer");
14550412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
14560412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        synchronized (mIdleTimerLock) {
145777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            final IdleTimerParams params = mActiveIdleTimers.get(iface);
14580412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            if (params == null || --(params.networkCount) > 0) {
14590412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                return;
14600412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            }
14610412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
14620412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            try {
14630412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                mConnector.execute("idletimer", "remove", iface,
146477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                        Integer.toString(params.timeout), Integer.toString(params.type));
14650412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            } catch (NativeDaemonConnectorException e) {
14660412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai                throw e.rethrowAsParcelableException();
14670412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            }
14680412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai            mActiveIdleTimers.remove(iface);
14692ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn            mDaemonHandler.post(new Runnable() {
147077b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                @Override public void run() {
14712ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                    notifyInterfaceClassActivity(params.type,
14722ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                            DataConnectionRealTimeInfo.DC_POWER_STATE_LOW,
14732ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                            SystemClock.elapsedRealtimeNanos(), false);
147477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                }
147577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            });
14760412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai        }
14770412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    }
14780412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai
14790412423f06ec633203b96f68b51f0720c33a2473Haoyu Bai    @Override
1480e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    public NetworkStats getNetworkStatsSummaryDev() {
14814529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
14829a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        try {
14839a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey            return mStatsFactory.readNetworkStatsSummaryDev();
14849a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        } catch (IOException e) {
14859a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey            throw new IllegalStateException(e);
14869a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        }
1487e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    }
1488e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey
1489e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    @Override
1490e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    public NetworkStats getNetworkStatsSummaryXt() {
1491e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
14929a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        try {
14939a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey            return mStatsFactory.readNetworkStatsSummaryXt();
14949a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        } catch (IOException e) {
14959a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey            throw new IllegalStateException(e);
14969a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        }
149791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat    }
149891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat
1499eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey    @Override
15009a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey    public NetworkStats getNetworkStatsDetail() {
15014529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
15029a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        try {
1503d0c5b9abed60b7bc056d026bf0f2b2235410fb70Dianne Hackborn            return mStatsFactory.readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
15049a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        } catch (IOException e) {
15059a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey            throw new IllegalStateException(e);
15069a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        }
150791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat    }
150891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat
1509eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey    @Override
151041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    public void setInterfaceQuota(String iface, long quotaBytes) {
15114529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1512b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
1513350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        // silently discard when control disabled
1514350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        // TODO: eventually migrate to be always enabled
1515350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        if (!mBandwidthControlEnabled) return;
1516350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
151741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        synchronized (mQuotaLock) {
1518b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            if (mActiveQuotas.containsKey(iface)) {
151941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                throw new IllegalStateException("iface " + iface + " already has quota");
1520b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            }
1521b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
1522b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            try {
152341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                // TODO: support quota shared across interfaces
1524ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                mConnector.execute("bandwidth", "setiquota", iface, quotaBytes);
1525b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mActiveQuotas.put(iface, quotaBytes);
1526b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            } catch (NativeDaemonConnectorException e) {
1527276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey                throw e.rethrowAsParcelableException();
1528b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            }
152950fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma        }
153050fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma    }
153150fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma
153250fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma    @Override
1533b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    public void removeInterfaceQuota(String iface) {
15344529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1535b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
1536350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        // silently discard when control disabled
1537350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        // TODO: eventually migrate to be always enabled
1538350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        if (!mBandwidthControlEnabled) return;
1539350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
154041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        synchronized (mQuotaLock) {
1541b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            if (!mActiveQuotas.containsKey(iface)) {
1542b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey                // TODO: eventually consider throwing
1543b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey                return;
1544b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            }
1545b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
1546b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            mActiveQuotas.remove(iface);
1547b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            mActiveAlerts.remove(iface);
154838ddeaa67e52810da5db42895edb74b79111ec53Jeff Sharkey
1549b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            try {
155041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                // TODO: support quota shared across interfaces
1551ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                mConnector.execute("bandwidth", "removeiquota", iface);
1552b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            } catch (NativeDaemonConnectorException e) {
1553276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey                throw e.rethrowAsParcelableException();
1554b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            }
1555b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey        }
1556b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    }
1557b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
1558b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    @Override
155941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    public void setInterfaceAlert(String iface, long alertBytes) {
15604529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
156141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
156241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // silently discard when control disabled
156341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // TODO: eventually migrate to be always enabled
156441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        if (!mBandwidthControlEnabled) return;
156541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
156641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // quick sanity check
1567b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        if (!mActiveQuotas.containsKey(iface)) {
156841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            throw new IllegalStateException("setting alert requires existing quota on iface");
156941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
157041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
157141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        synchronized (mQuotaLock) {
1572b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            if (mActiveAlerts.containsKey(iface)) {
157341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                throw new IllegalStateException("iface " + iface + " already has alert");
157441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            }
157541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
157641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            try {
157741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                // TODO: support alert shared across interfaces
1578ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                mConnector.execute("bandwidth", "setinterfacealert", iface, alertBytes);
1579b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mActiveAlerts.put(iface, alertBytes);
158041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            } catch (NativeDaemonConnectorException e) {
1581276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey                throw e.rethrowAsParcelableException();
158241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            }
158341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
158441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
158541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
158641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    @Override
158741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    public void removeInterfaceAlert(String iface) {
15884529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
158941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
159041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // silently discard when control disabled
159141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // TODO: eventually migrate to be always enabled
159241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        if (!mBandwidthControlEnabled) return;
159341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
159441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        synchronized (mQuotaLock) {
1595b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            if (!mActiveAlerts.containsKey(iface)) {
159641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                // TODO: eventually consider throwing
159741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                return;
159841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            }
159941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
160041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            try {
160141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                // TODO: support alert shared across interfaces
1602ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                mConnector.execute("bandwidth", "removeinterfacealert", iface);
1603b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey                mActiveAlerts.remove(iface);
160441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            } catch (NativeDaemonConnectorException e) {
1605276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey                throw e.rethrowAsParcelableException();
160641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            }
160741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
160841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
160941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
161041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    @Override
161141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    public void setGlobalAlert(long alertBytes) {
16124529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
161341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
161441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // silently discard when control disabled
161541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        // TODO: eventually migrate to be always enabled
161641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        if (!mBandwidthControlEnabled) return;
161741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
161841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        try {
1619ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute("bandwidth", "setglobalalert", alertBytes);
162041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        } catch (NativeDaemonConnectorException e) {
1621276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
162241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
162341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
162441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
162541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    @Override
1626b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey    public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
16274529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1628b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
1629350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        // silently discard when control disabled
1630350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        // TODO: eventually migrate to be always enabled
1631350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        if (!mBandwidthControlEnabled) return;
1632350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
1633b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey        synchronized (mQuotaLock) {
1634b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            final boolean oldRejectOnQuota = mUidRejectOnQuota.get(uid, false);
1635b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            if (oldRejectOnQuota == rejectOnQuotaInterfaces) {
1636b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey                // TODO: eventually consider throwing
1637b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey                return;
1638b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            }
1639b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey
1640b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            try {
1641ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                mConnector.execute("bandwidth",
1642ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey                        rejectOnQuotaInterfaces ? "addnaughtyapps" : "removenaughtyapps", uid);
1643b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey                if (rejectOnQuotaInterfaces) {
1644b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey                    mUidRejectOnQuota.put(uid, true);
1645b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey                } else {
1646b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey                    mUidRejectOnQuota.delete(uid);
1647b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey                }
1648b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            } catch (NativeDaemonConnectorException e) {
1649276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey                throw e.rethrowAsParcelableException();
1650b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey            }
165150fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma        }
165250fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma    }
165350fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma
165463d27a9233fed934340231f438493746084a681dJeff Sharkey    @Override
165563d27a9233fed934340231f438493746084a681dJeff Sharkey    public boolean isBandwidthControlEnabled() {
16564529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
165763d27a9233fed934340231f438493746084a681dJeff Sharkey        return mBandwidthControlEnabled;
165863d27a9233fed934340231f438493746084a681dJeff Sharkey    }
165963d27a9233fed934340231f438493746084a681dJeff Sharkey
166063d27a9233fed934340231f438493746084a681dJeff Sharkey    @Override
1661eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey    public NetworkStats getNetworkStatsUidDetail(int uid) {
16624529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
16639a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        try {
1664d0c5b9abed60b7bc056d026bf0f2b2235410fb70Dianne Hackborn            return mStatsFactory.readNetworkStatsDetail(uid, null, TAG_ALL, null);
16659a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        } catch (IOException e) {
16669a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey            throw new IllegalStateException(e);
16679a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey        }
1668eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey    }
1669eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey
1670cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    @Override
1671e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey    public NetworkStats getNetworkStatsTethering() {
16724529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1673cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey
1674cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
1675cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        try {
1676e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey            final NativeDaemonEvent[] events = mConnector.executeForList(
1677e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    "bandwidth", "gettetherstats");
1678e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey            for (NativeDaemonEvent event : events) {
1679e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                if (event.getCode() != TetheringStatsListResult) continue;
1680e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey
1681e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                // 114 ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets
1682e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                final StringTokenizer tok = new StringTokenizer(event.getMessage());
1683e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                try {
1684e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    final String ifaceIn = tok.nextToken();
1685e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    final String ifaceOut = tok.nextToken();
1686e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey
1687e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    final NetworkStats.Entry entry = new NetworkStats.Entry();
1688e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    entry.iface = ifaceOut;
1689e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    entry.uid = UID_TETHERING;
1690e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    entry.set = SET_DEFAULT;
1691e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    entry.tag = TAG_NONE;
1692e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    entry.rxBytes = Long.parseLong(tok.nextToken());
1693e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    entry.rxPackets = Long.parseLong(tok.nextToken());
1694e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    entry.txBytes = Long.parseLong(tok.nextToken());
1695e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    entry.txPackets = Long.parseLong(tok.nextToken());
1696e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    stats.combineValues(entry);
1697e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                } catch (NoSuchElementException e) {
1698e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    throw new IllegalStateException("problem parsing tethering stats: " + event);
1699e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                } catch (NumberFormatException e) {
1700e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                    throw new IllegalStateException("problem parsing tethering stats: " + event);
1701e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey                }
1702e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey            }
1703cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        } catch (NativeDaemonConnectorException e) {
1704276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
1705cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        }
1706e4984bea95a07dea0ef0259fefa1e52f0bbb1533Jeff Sharkey        return stats;
1707cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    }
1708cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey
1709af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
171013e817df516a803fbedeacca2c802a9fc1c1370fPaul Jensen    public void setDnsServersForNetwork(int netId, String[] servers, String domains) {
17114529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1712ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
1713829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti        Command cmd;
1714829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti        if (servers.length > 0) {
1715829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti            cmd = new Command("resolver", "setnetdns", netId,
1716829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti                    (domains == null ? "" : domains));
1717829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti            for (String s : servers) {
1718829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti                InetAddress a = NetworkUtils.numericToInetAddress(s);
1719829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti                if (a.isAnyLocalAddress() == false) {
1720829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti                    cmd.appendArg(a.getHostAddress());
1721829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti                }
17227475c0cea622f126af966c3b5b9741f547e83450Mattias Falk            }
1723829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti        } else {
1724829dfa7cd80faa61b3f63c455f81411571144f82Lorenzo Colitti            cmd = new Command("resolver", "clearnetdns", netId);
1725ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        }
1726ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey
1727ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey        try {
1728ba2896e939f359e5857149f1a27212db71be012bJeff Sharkey            mConnector.execute(cmd);
17297475c0cea622f126af966c3b5b9741f547e83450Mattias Falk        } catch (NativeDaemonConnectorException e) {
1730276642baf11e05700ef24447dc4271f16ce69b50Jeff Sharkey            throw e.rethrowAsParcelableException();
17317475c0cea622f126af966c3b5b9741f547e83450Mattias Falk        }
17327475c0cea622f126af966c3b5b9741f547e83450Mattias Falk    }
17337475c0cea622f126af966c3b5b9741f547e83450Mattias Falk
1734af75c33e8d7f1a27c6c0d71820730ea8525019a3Jeff Sharkey    @Override
17356bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    public void addVpnUidRanges(int netId, UidRange[] ranges) {
17363277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
17376bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND];
17386bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        argv[0] = "users";
17396bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        argv[1] = "add";
17406bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        argv[2] = netId;
17416bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        int argc = 3;
17426bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        // Avoid overly long commands by limiting number of UID ranges per command.
17436bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        for (int i = 0; i < ranges.length; i++) {
17446bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            argv[argc++] = ranges[i].toString();
17456bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            if (i == (ranges.length - 1) || argc == argv.length) {
17466bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                try {
17476bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                    mConnector.execute("network", Arrays.copyOf(argv, argc));
17486bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                } catch (NativeDaemonConnectorException e) {
17496bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                    throw e.rethrowAsParcelableException();
17506bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                }
17516bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                argc = 3;
17526bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            }
17533277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker        }
17543277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker    }
17553277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker
17563277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker    @Override
17576bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    public void removeVpnUidRanges(int netId, UidRange[] ranges) {
17583277620a69b6b9f27126f0b2651ea4293731cd09Chad Brubaker        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
17596bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND];
17606bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        argv[0] = "users";
17616bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        argv[1] = "remove";
17626bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        argv[2] = netId;
17636bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        int argc = 3;
17646bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        // Avoid overly long commands by limiting number of UID ranges per command.
17656bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        for (int i = 0; i < ranges.length; i++) {
17666bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            argv[argc++] = ranges[i].toString();
17676bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            if (i == (ranges.length - 1) || argc == argv.length) {
17686bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                try {
17696bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                    mConnector.execute("network", Arrays.copyOf(argv, argc));
17706bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                } catch (NativeDaemonConnectorException e) {
17716bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                    throw e.rethrowAsParcelableException();
17726bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                }
17736bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen                argc = 3;
17746bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            }
1775cca54c4decc70dd49382cc7ebe297845c94ee706Chad Brubaker        }
1776cca54c4decc70dd49382cc7ebe297845c94ee706Chad Brubaker    }
1777cca54c4decc70dd49382cc7ebe297845c94ee706Chad Brubaker
1778cca54c4decc70dd49382cc7ebe297845c94ee706Chad Brubaker    @Override
1779b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen    public void flushNetworkDnsCache(int netId) {
1780b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1781b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen        try {
1782b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen            mConnector.execute("resolver", "flushnet", netId);
1783b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen        } catch (NativeDaemonConnectorException e) {
1784b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen            throw e.rethrowAsParcelableException();
1785b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen        }
1786b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen    }
1787b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen
1788b69a3a8eaade042aa5b4d17f9b0dfd565c2e4a97Paul Jensen    @Override
1789c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    public void setFirewallEnabled(boolean enabled) {
1790f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        enforceSystemUid();
1791c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        try {
1792c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            mConnector.execute("firewall", enabled ? "enable" : "disable");
1793c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            mFirewallEnabled = enabled;
1794c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        } catch (NativeDaemonConnectorException e) {
1795c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            throw e.rethrowAsParcelableException();
1796c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        }
1797c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    }
1798c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey
1799c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    @Override
1800c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    public boolean isFirewallEnabled() {
1801f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        enforceSystemUid();
1802c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        return mFirewallEnabled;
1803c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    }
1804c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey
1805c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    @Override
18062c0929850ae495d54efb91a68e4bbd29a2e0ec95Jeff Sharkey    public void setFirewallInterfaceRule(String iface, boolean allow) {
1807f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        enforceSystemUid();
1808c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        Preconditions.checkState(mFirewallEnabled);
1809a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        final String rule = allow ? "allow" : "deny";
1810c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        try {
1811c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            mConnector.execute("firewall", "set_interface_rule", iface, rule);
1812c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        } catch (NativeDaemonConnectorException e) {
1813c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            throw e.rethrowAsParcelableException();
1814c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        }
1815c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    }
1816c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey
1817c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    @Override
18182c0929850ae495d54efb91a68e4bbd29a2e0ec95Jeff Sharkey    public void setFirewallEgressSourceRule(String addr, boolean allow) {
1819f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        enforceSystemUid();
1820c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        Preconditions.checkState(mFirewallEnabled);
1821a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        final String rule = allow ? "allow" : "deny";
1822c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        try {
1823c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            mConnector.execute("firewall", "set_egress_source_rule", addr, rule);
1824c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        } catch (NativeDaemonConnectorException e) {
1825c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            throw e.rethrowAsParcelableException();
1826c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        }
1827c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    }
1828c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey
1829c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    @Override
18302c0929850ae495d54efb91a68e4bbd29a2e0ec95Jeff Sharkey    public void setFirewallEgressDestRule(String addr, int port, boolean allow) {
1831f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        enforceSystemUid();
1832c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        Preconditions.checkState(mFirewallEnabled);
1833a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        final String rule = allow ? "allow" : "deny";
1834c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        try {
1835c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            mConnector.execute("firewall", "set_egress_dest_rule", addr, port, rule);
1836c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        } catch (NativeDaemonConnectorException e) {
1837c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            throw e.rethrowAsParcelableException();
1838c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        }
1839c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    }
1840c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey
1841c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    @Override
18422c0929850ae495d54efb91a68e4bbd29a2e0ec95Jeff Sharkey    public void setFirewallUidRule(int uid, boolean allow) {
1843f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        enforceSystemUid();
1844c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        Preconditions.checkState(mFirewallEnabled);
1845a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        final String rule = allow ? "allow" : "deny";
1846c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        try {
1847c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            mConnector.execute("firewall", "set_uid_rule", uid, rule);
1848c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        } catch (NativeDaemonConnectorException e) {
1849c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey            throw e.rethrowAsParcelableException();
1850c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        }
1851c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    }
1852c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey
1853f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey    private static void enforceSystemUid() {
1854f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        final int uid = Binder.getCallingUid();
1855f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        if (uid != Process.SYSTEM_UID) {
1856f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey            throw new SecurityException("Only available to AID_SYSTEM");
1857f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey        }
1858f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey    }
1859f56e2435b64f9638e029777fa9492d42f157033eJeff Sharkey
1860c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey    @Override
186179751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti    public void startClatd(String interfaceName) throws IllegalStateException {
186279751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
186379751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti
186479751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        try {
186579751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti            mConnector.execute("clatd", "start", interfaceName);
186679751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        } catch (NativeDaemonConnectorException e) {
186779751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti            throw e.rethrowAsParcelableException();
186879751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        }
186979751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti    }
187079751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti
187179751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti    @Override
1872954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti    public void stopClatd(String interfaceName) throws IllegalStateException {
187379751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
187479751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti
187579751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        try {
1876954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti            mConnector.execute("clatd", "stop", interfaceName);
187779751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        } catch (NativeDaemonConnectorException e) {
187879751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti            throw e.rethrowAsParcelableException();
187979751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        }
188079751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti    }
188179751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti
188279751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti    @Override
1883954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti    public boolean isClatdStarted(String interfaceName) {
188479751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
188579751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti
188679751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        final NativeDaemonEvent event;
188779751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        try {
1888954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti            event = mConnector.execute("clatd", "status", interfaceName);
188979751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        } catch (NativeDaemonConnectorException e) {
189079751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti            throw e.rethrowAsParcelableException();
189179751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        }
189279751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti
189379751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        event.checkCode(ClatdStatusResult);
189479751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti        return event.getMessage().endsWith("started");
189579751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti    }
189679751848d1c3a5139eb5ccd6ddecaf84c2a09783Lorenzo Colitti
189777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    @Override
189877b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    public void registerNetworkActivityListener(INetworkActivityListener listener) {
189977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        mNetworkActivityListeners.register(listener);
190077b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    }
190177b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
190277b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    @Override
190377b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
190477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        mNetworkActivityListeners.unregister(listener);
190577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    }
190677b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
190777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    @Override
190877b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    public boolean isNetworkActive() {
190977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        synchronized (mNetworkActivityListeners) {
191077b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            return mNetworkActive || mActiveIdleTimers.isEmpty();
191177b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        }
191277b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    }
191377b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
191477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    private void reportNetworkActive() {
191577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        final int length = mNetworkActivityListeners.beginBroadcast();
19162c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        try {
19172c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            for (int i = 0; i < length; i++) {
19182c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                try {
19192c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                    mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
19202c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RemoteException e) {
19212c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                } catch (RuntimeException e) {
19222c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt                }
192377b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            }
19242c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt        } finally {
19252c9f5475beabcc1c71d88b7c88d6029c3245be65Robert Greenwalt            mNetworkActivityListeners.finishBroadcast();
192677b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        }
192777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn    }
192877b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
19298b47b3601f82f299bb8c135af0639b72b67230e6Mattias Falk    /** {@inheritDoc} */
19307b4596fd68a24643145e33f3dc4da9285d0f53aaJeff Sharkey    @Override
1931fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey    public void monitor() {
1932fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey        if (mConnector != null) {
1933fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey            mConnector.monitor();
1934fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey        }
1935fa23c5ae226c1a1d39f89c5c87d4f340e91d90e0Jeff Sharkey    }
193647eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey
193747eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey    @Override
193847eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
193947eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey        mContext.enforceCallingOrSelfPermission(DUMP, TAG);
194047eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey
1941470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt        pw.println("NetworkManagementService NativeDaemonConnector Log:");
1942470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt        mConnector.dump(fd, pw, args);
1943470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt        pw.println();
1944470fd72a06390d7a6b854583afd0ed76ce0a03eeRobert Greenwalt
194547eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey        pw.print("Bandwidth control enabled: "); pw.println(mBandwidthControlEnabled);
19462ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio);
19472ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn                pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio);
19482ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn        pw.print("mNetworkActive="); pw.println(mNetworkActive);
194947eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey
195047eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey        synchronized (mQuotaLock) {
1951b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
1952b24a78589b2bee4a86d5c864dd69169e134a339bJeff Sharkey            pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
195347eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey        }
195447eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey
195547eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey        synchronized (mUidRejectOnQuota) {
195647eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey            pw.print("UID reject on quota ifaces: [");
195747eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey            final int size = mUidRejectOnQuota.size();
195847eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey            for (int i = 0; i < size; i++) {
195947eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey                pw.print(mUidRejectOnQuota.keyAt(i));
196047eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey                if (i < size - 1) pw.print(",");
196147eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey            }
196247eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey            pw.println("]");
196347eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey        }
1964c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey
196577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        synchronized (mIdleTimerLock) {
196677b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            pw.println("Idle timers:");
196777b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
196877b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                pw.print("  "); pw.print(ent.getKey()); pw.println(":");
196977b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                IdleTimerParams params = ent.getValue();
197077b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                pw.print("    timeout="); pw.print(params.timeout);
197177b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                pw.print(" type="); pw.print(params.type);
197277b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn                pw.print(" networkCount="); pw.println(params.networkCount);
197377b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn            }
197477b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn        }
197577b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn
1976c268f0b19efd0b6c6c89c21be0893787f3cc9cf7Jeff Sharkey        pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
197747eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey    }
19789ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt
1979568891d9282383747c418a59ee714281726f390aRobert Greenwalt    @Override
19806bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    public void createPhysicalNetwork(int netId) {
19819ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
19829ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt
19839ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt        try {
1984992f25257938ecc0378514f21c6e6e6375272976Paul Jensen            mConnector.execute("network", "create", netId);
19859ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt        } catch (NativeDaemonConnectorException e) {
19869ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt            throw e.rethrowAsParcelableException();
19879ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt        }
19889ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt    }
19899ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt
1990568891d9282383747c418a59ee714281726f390aRobert Greenwalt    @Override
19918cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran    public void createVirtualNetwork(int netId, boolean hasDNS, boolean secure) {
19926bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
19936bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
19946bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        try {
19958cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran            mConnector.execute("network", "create", netId, "vpn", hasDNS ? "1" : "0",
19968cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran                    secure ? "1" : "0");
19976bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        } catch (NativeDaemonConnectorException e) {
19986bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            throw e.rethrowAsParcelableException();
19996bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        }
20006bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    }
20016bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
20026bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    @Override
20039ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt    public void removeNetwork(int netId) {
20049ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
20059ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt
20069ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt        try {
20079ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt            mConnector.execute("network", "destroy", netId);
20089ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt        } catch (NativeDaemonConnectorException e) {
20099ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt            throw e.rethrowAsParcelableException();
20109ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt        }
20119ba9c58e4a249456794fbfb9989f27bd846d067eRobert Greenwalt    }
2012568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2013568891d9282383747c418a59ee714281726f390aRobert Greenwalt    @Override
2014992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    public void addInterfaceToNetwork(String iface, int netId) {
2015a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        modifyInterfaceInNetwork("add", "" + netId, iface);
2016992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    }
2017992f25257938ecc0378514f21c6e6e6375272976Paul Jensen
2018992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    @Override
2019992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    public void removeInterfaceFromNetwork(String iface, int netId) {
2020a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        modifyInterfaceInNetwork("remove", "" + netId, iface);
2021a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    }
2022992f25257938ecc0378514f21c6e6e6375272976Paul Jensen
2023a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    private void modifyInterfaceInNetwork(String action, String netId, String iface) {
2024a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2025992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        try {
2026a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran            mConnector.execute("network", "interface", action, netId, iface);
2027992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        } catch (NativeDaemonConnectorException e) {
2028992f25257938ecc0378514f21c6e6e6375272976Paul Jensen            throw e.rethrowAsParcelableException();
2029992f25257938ecc0378514f21c6e6e6375272976Paul Jensen        }
2030992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    }
2031992f25257938ecc0378514f21c6e6e6375272976Paul Jensen
2032992f25257938ecc0378514f21c6e6e6375272976Paul Jensen    @Override
2033913c895216c0cb248ed0ce910e69dd84b285c064Robert Greenwalt    public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
2034568891d9282383747c418a59ee714281726f390aRobert Greenwalt        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2035568891d9282383747c418a59ee714281726f390aRobert Greenwalt
203603666c705ddabe0e7c5869ab69c2ca8b964164e9Sreeram Ramachandran        final Command cmd = new Command("network", "route", "legacy", uid, "add", netId);
2037568891d9282383747c418a59ee714281726f390aRobert Greenwalt
20381fbcb2719828f16aec8b2d742a20b98e4a2cf17cSreeram Ramachandran        // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
2039cc91c7b804a079f7b20404827277c61dd403805fSreeram Ramachandran        final LinkAddress la = routeInfo.getDestinationLinkAddress();
2040568891d9282383747c418a59ee714281726f390aRobert Greenwalt        cmd.appendArg(routeInfo.getInterface());
20417dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
20421fbcb2719828f16aec8b2d742a20b98e4a2cf17cSreeram Ramachandran        if (routeInfo.hasGateway()) {
20431fbcb2719828f16aec8b2d742a20b98e4a2cf17cSreeram Ramachandran            cmd.appendArg(routeInfo.getGateway().getHostAddress());
20441fbcb2719828f16aec8b2d742a20b98e4a2cf17cSreeram Ramachandran        }
2045568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2046568891d9282383747c418a59ee714281726f390aRobert Greenwalt        try {
2047568891d9282383747c418a59ee714281726f390aRobert Greenwalt            mConnector.execute(cmd);
2048568891d9282383747c418a59ee714281726f390aRobert Greenwalt        } catch (NativeDaemonConnectorException e) {
2049568891d9282383747c418a59ee714281726f390aRobert Greenwalt            throw e.rethrowAsParcelableException();
2050568891d9282383747c418a59ee714281726f390aRobert Greenwalt        }
2051568891d9282383747c418a59ee714281726f390aRobert Greenwalt    }
2052568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2053568891d9282383747c418a59ee714281726f390aRobert Greenwalt    @Override
2054f047f2a8f49cd06d9cb94238861f4acce937d87bSreeram Ramachandran    public void setDefaultNetId(int netId) {
2055568891d9282383747c418a59ee714281726f390aRobert Greenwalt        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2056568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2057568891d9282383747c418a59ee714281726f390aRobert Greenwalt        try {
2058f047f2a8f49cd06d9cb94238861f4acce937d87bSreeram Ramachandran            mConnector.execute("network", "default", "set", netId);
2059568891d9282383747c418a59ee714281726f390aRobert Greenwalt        } catch (NativeDaemonConnectorException e) {
2060568891d9282383747c418a59ee714281726f390aRobert Greenwalt            throw e.rethrowAsParcelableException();
2061568891d9282383747c418a59ee714281726f390aRobert Greenwalt        }
2062568891d9282383747c418a59ee714281726f390aRobert Greenwalt    }
2063568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2064568891d9282383747c418a59ee714281726f390aRobert Greenwalt    @Override
2065568891d9282383747c418a59ee714281726f390aRobert Greenwalt    public void clearDefaultNetId() {
2066568891d9282383747c418a59ee714281726f390aRobert Greenwalt        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2067568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2068568891d9282383747c418a59ee714281726f390aRobert Greenwalt        try {
2069568891d9282383747c418a59ee714281726f390aRobert Greenwalt            mConnector.execute("network", "default", "clear");
2070568891d9282383747c418a59ee714281726f390aRobert Greenwalt        } catch (NativeDaemonConnectorException e) {
2071568891d9282383747c418a59ee714281726f390aRobert Greenwalt            throw e.rethrowAsParcelableException();
2072568891d9282383747c418a59ee714281726f390aRobert Greenwalt        }
2073568891d9282383747c418a59ee714281726f390aRobert Greenwalt    }
2074568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2075568891d9282383747c418a59ee714281726f390aRobert Greenwalt    @Override
2076e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran    public void setPermission(String permission, int[] uids) {
2077568891d9282383747c418a59ee714281726f390aRobert Greenwalt        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2078568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2079e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        Object[] argv = new Object[4 + MAX_UID_RANGES_PER_COMMAND];
2080e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        argv[0] = "permission";
2081e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        argv[1] = "user";
2082e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        argv[2] = "set";
2083e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        argv[3] = permission;
2084e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        int argc = 4;
2085e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        // Avoid overly long commands by limiting number of UIDs per command.
2086e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        for (int i = 0; i < uids.length; ++i) {
2087e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran            argv[argc++] = uids[i];
2088e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran            if (i == uids.length - 1 || argc == argv.length) {
2089e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                try {
2090e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                    mConnector.execute("network", Arrays.copyOf(argv, argc));
2091e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                } catch (NativeDaemonConnectorException e) {
2092e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                    throw e.rethrowAsParcelableException();
2093e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                }
2094e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                argc = 4;
2095e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran            }
2096568891d9282383747c418a59ee714281726f390aRobert Greenwalt        }
2097568891d9282383747c418a59ee714281726f390aRobert Greenwalt    }
2098568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2099568891d9282383747c418a59ee714281726f390aRobert Greenwalt    @Override
2100568891d9282383747c418a59ee714281726f390aRobert Greenwalt    public void clearPermission(int[] uids) {
2101568891d9282383747c418a59ee714281726f390aRobert Greenwalt        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2102568891d9282383747c418a59ee714281726f390aRobert Greenwalt
2103e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND];
2104e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        argv[0] = "permission";
2105e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        argv[1] = "user";
2106e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        argv[2] = "clear";
2107e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        int argc = 3;
2108e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        // Avoid overly long commands by limiting number of UIDs per command.
2109e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran        for (int i = 0; i < uids.length; ++i) {
2110e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran            argv[argc++] = uids[i];
2111e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran            if (i == uids.length - 1 || argc == argv.length) {
2112e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                try {
2113e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                    mConnector.execute("network", Arrays.copyOf(argv, argc));
2114e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                } catch (NativeDaemonConnectorException e) {
2115e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                    throw e.rethrowAsParcelableException();
2116e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                }
2117e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran                argc = 3;
2118e4a05afe85f15472325db9c535ef81f409fb6070Sreeram Ramachandran            }
2119568891d9282383747c418a59ee714281726f390aRobert Greenwalt        }
2120568891d9282383747c418a59ee714281726f390aRobert Greenwalt    }
21216bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
21226bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    @Override
21236bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    public void allowProtect(int uid) {
21246bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
21256bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
21266bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        try {
21276bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            mConnector.execute("network", "protect", "allow", uid);
21286bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        } catch (NativeDaemonConnectorException e) {
21296bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            throw e.rethrowAsParcelableException();
21306bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        }
21316bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    }
21326bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
21336bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    @Override
21346bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    public void denyProtect(int uid) {
21356bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
21366bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
21376bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        try {
21386bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            mConnector.execute("network", "protect", "deny", uid);
21396bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        } catch (NativeDaemonConnectorException e) {
21406bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen            throw e.rethrowAsParcelableException();
21416bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        }
21426bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    }
21436bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
2144a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    @Override
2145a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) {
2146a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        modifyInterfaceInNetwork("add", "local", iface);
2147a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran
2148a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        for (RouteInfo route : routes) {
2149a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran            if (!route.isDefaultRoute()) {
2150a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran                modifyRoute("add", "local", route);
2151a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran            }
2152a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        }
2153a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    }
2154a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran
2155a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    @Override
2156a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    public void removeInterfaceFromLocalNetwork(String iface) {
2157a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran        modifyInterfaceInNetwork("remove", "local", iface);
2158a77760d74ad544bbd4f6310fd28b395f24c5467dSreeram Ramachandran    }
2159873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat}
2160