• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server;
18 
19 import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
20 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
21 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
22 import static android.net.ConnectivityManager.isNetworkTypeValid;
23 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
24 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
25 
26 import android.bluetooth.BluetoothTetheringDataTracker;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.pm.PackageManager;
31 import android.database.ContentObserver;
32 import android.net.ConnectivityManager;
33 import android.net.DummyDataStateTracker;
34 import android.net.EthernetDataTracker;
35 import android.net.IConnectivityManager;
36 import android.net.INetworkPolicyListener;
37 import android.net.INetworkPolicyManager;
38 import android.net.INetworkStatsService;
39 import android.net.LinkAddress;
40 import android.net.LinkProperties;
41 import android.net.LinkProperties.CompareResult;
42 import android.net.MobileDataStateTracker;
43 import android.net.NetworkConfig;
44 import android.net.NetworkInfo;
45 import android.net.NetworkInfo.DetailedState;
46 import android.net.NetworkQuotaInfo;
47 import android.net.NetworkState;
48 import android.net.NetworkStateTracker;
49 import android.net.NetworkUtils;
50 import android.net.Proxy;
51 import android.net.ProxyProperties;
52 import android.net.RouteInfo;
53 import android.net.wifi.WifiStateTracker;
54 import android.os.Binder;
55 import android.os.FileUtils;
56 import android.os.Handler;
57 import android.os.HandlerThread;
58 import android.os.IBinder;
59 import android.os.INetworkManagementService;
60 import android.os.Looper;
61 import android.os.Message;
62 import android.os.ParcelFileDescriptor;
63 import android.os.PowerManager;
64 import android.os.RemoteException;
65 import android.os.ServiceManager;
66 import android.os.SystemProperties;
67 import android.provider.Settings;
68 import android.text.TextUtils;
69 import android.util.EventLog;
70 import android.util.Slog;
71 import android.util.SparseIntArray;
72 
73 import com.android.internal.net.LegacyVpnInfo;
74 import com.android.internal.net.VpnConfig;
75 import com.android.internal.telephony.Phone;
76 import com.android.server.am.BatteryStatsService;
77 import com.android.server.connectivity.Tethering;
78 import com.android.server.connectivity.Vpn;
79 import com.google.android.collect.Lists;
80 import com.google.android.collect.Sets;
81 
82 import java.io.FileDescriptor;
83 import java.io.IOException;
84 import java.io.PrintWriter;
85 import java.net.Inet4Address;
86 import java.net.Inet6Address;
87 import java.net.InetAddress;
88 import java.net.UnknownHostException;
89 import java.util.ArrayList;
90 import java.util.Arrays;
91 import java.util.Collection;
92 import java.util.GregorianCalendar;
93 import java.util.HashSet;
94 import java.util.List;
95 
96 /**
97  * @hide
98  */
99 public class ConnectivityService extends IConnectivityManager.Stub {
100 
101     private static final boolean DBG = true;
102     private static final boolean VDBG = false;
103     private static final String TAG = "ConnectivityService";
104 
105     private static final boolean LOGD_RULES = false;
106 
107     // how long to wait before switching back to a radio's default network
108     private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
109     // system property that can override the above value
110     private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
111             "android.telephony.apn-restore";
112 
113     // used in recursive route setting to add gateways for the host for which
114     // a host route was requested.
115     private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
116 
117     private Tethering mTethering;
118     private boolean mTetheringConfigValid = false;
119 
120     private Vpn mVpn;
121 
122     /** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
123     private Object mRulesLock = new Object();
124     /** Currently active network rules by UID. */
125     private SparseIntArray mUidRules = new SparseIntArray();
126     /** Set of ifaces that are costly. */
127     private HashSet<String> mMeteredIfaces = Sets.newHashSet();
128 
129     /**
130      * Sometimes we want to refer to the individual network state
131      * trackers separately, and sometimes we just want to treat them
132      * abstractly.
133      */
134     private NetworkStateTracker mNetTrackers[];
135 
136     /**
137      * The link properties that define the current links
138      */
139     private LinkProperties mCurrentLinkProperties[];
140 
141     /**
142      * A per Net list of the PID's that requested access to the net
143      * used both as a refcount and for per-PID DNS selection
144      */
145     private List mNetRequestersPids[];
146 
147     // priority order of the nettrackers
148     // (excluding dynamically set mNetworkPreference)
149     // TODO - move mNetworkTypePreference into this
150     private int[] mPriorityList;
151 
152     private Context mContext;
153     private int mNetworkPreference;
154     private int mActiveDefaultNetwork = -1;
155     // 0 is full bad, 100 is full good
156     private int mDefaultInetCondition = 0;
157     private int mDefaultInetConditionPublished = 0;
158     private boolean mInetConditionChangeInFlight = false;
159     private int mDefaultConnectionSequence = 0;
160 
161     private Object mDnsLock = new Object();
162     private int mNumDnsEntries;
163     private boolean mDnsOverridden = false;
164 
165     private boolean mTestMode;
166     private static ConnectivityService sServiceInstance;
167 
168     private INetworkManagementService mNetd;
169     private INetworkPolicyManager mPolicyManager;
170 
171     private static final int ENABLED  = 1;
172     private static final int DISABLED = 0;
173 
174     // Share the event space with NetworkStateTracker (which can't see this
175     // internal class but sends us events).  If you change these, change
176     // NetworkStateTracker.java too.
177     private static final int MIN_NETWORK_STATE_TRACKER_EVENT = 1;
178     private static final int MAX_NETWORK_STATE_TRACKER_EVENT = 100;
179 
180     /**
181      * used internally as a delayed event to make us switch back to the
182      * default network
183      */
184     private static final int EVENT_RESTORE_DEFAULT_NETWORK =
185             MAX_NETWORK_STATE_TRACKER_EVENT + 1;
186 
187     /**
188      * used internally to change our mobile data enabled flag
189      */
190     private static final int EVENT_CHANGE_MOBILE_DATA_ENABLED =
191             MAX_NETWORK_STATE_TRACKER_EVENT + 2;
192 
193     /**
194      * used internally to change our network preference setting
195      * arg1 = networkType to prefer
196      */
197     private static final int EVENT_SET_NETWORK_PREFERENCE =
198             MAX_NETWORK_STATE_TRACKER_EVENT + 3;
199 
200     /**
201      * used internally to synchronize inet condition reports
202      * arg1 = networkType
203      * arg2 = condition (0 bad, 100 good)
204      */
205     private static final int EVENT_INET_CONDITION_CHANGE =
206             MAX_NETWORK_STATE_TRACKER_EVENT + 4;
207 
208     /**
209      * used internally to mark the end of inet condition hold periods
210      * arg1 = networkType
211      */
212     private static final int EVENT_INET_CONDITION_HOLD_END =
213             MAX_NETWORK_STATE_TRACKER_EVENT + 5;
214 
215     /**
216      * used internally to set enable/disable cellular data
217      * arg1 = ENBALED or DISABLED
218      */
219     private static final int EVENT_SET_MOBILE_DATA =
220             MAX_NETWORK_STATE_TRACKER_EVENT + 7;
221 
222     /**
223      * used internally to clear a wakelock when transitioning
224      * from one net to another
225      */
226     private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK =
227             MAX_NETWORK_STATE_TRACKER_EVENT + 8;
228 
229     /**
230      * used internally to reload global proxy settings
231      */
232     private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY =
233             MAX_NETWORK_STATE_TRACKER_EVENT + 9;
234 
235     /**
236      * used internally to set external dependency met/unmet
237      * arg1 = ENABLED (met) or DISABLED (unmet)
238      * arg2 = NetworkType
239      */
240     private static final int EVENT_SET_DEPENDENCY_MET =
241             MAX_NETWORK_STATE_TRACKER_EVENT + 10;
242 
243     /**
244      * used internally to restore DNS properties back to the
245      * default network
246      */
247     private static final int EVENT_RESTORE_DNS =
248             MAX_NETWORK_STATE_TRACKER_EVENT + 11;
249 
250     /**
251      * used internally to send a sticky broadcast delayed.
252      */
253     private static final int EVENT_SEND_STICKY_BROADCAST_INTENT =
254             MAX_NETWORK_STATE_TRACKER_EVENT + 12;
255 
256     /**
257      * Used internally to
258      * {@link NetworkStateTracker#setPolicyDataEnable(boolean)}.
259      */
260     private static final int EVENT_SET_POLICY_DATA_ENABLE = MAX_NETWORK_STATE_TRACKER_EVENT + 13;
261 
262     private Handler mHandler;
263 
264     // list of DeathRecipients used to make sure features are turned off when
265     // a process dies
266     private List<FeatureUser> mFeatureUsers;
267 
268     private boolean mSystemReady;
269     private Intent mInitialBroadcast;
270 
271     private PowerManager.WakeLock mNetTransitionWakeLock;
272     private String mNetTransitionWakeLockCausedBy = "";
273     private int mNetTransitionWakeLockSerialNumber;
274     private int mNetTransitionWakeLockTimeout;
275 
276     private InetAddress mDefaultDns;
277 
278     // this collection is used to refcount the added routes - if there are none left
279     // it's time to remove the route from the route table
280     private Collection<RouteInfo> mAddedRoutes = new ArrayList<RouteInfo>();
281 
282     // used in DBG mode to track inet condition reports
283     private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
284     private ArrayList mInetLog;
285 
286     // track the current default http proxy - tell the world if we get a new one (real change)
287     private ProxyProperties mDefaultProxy = null;
288     private Object mDefaultProxyLock = new Object();
289     private boolean mDefaultProxyDisabled = false;
290 
291     // track the global proxy.
292     private ProxyProperties mGlobalProxy = null;
293     private final Object mGlobalProxyLock = new Object();
294 
295     private SettingsObserver mSettingsObserver;
296 
297     NetworkConfig[] mNetConfigs;
298     int mNetworksDefined;
299 
300     private static class RadioAttributes {
301         public int mSimultaneity;
302         public int mType;
RadioAttributes(String init)303         public RadioAttributes(String init) {
304             String fragments[] = init.split(",");
305             mType = Integer.parseInt(fragments[0]);
306             mSimultaneity = Integer.parseInt(fragments[1]);
307         }
308     }
309     RadioAttributes[] mRadioAttributes;
310 
311     // the set of network types that can only be enabled by system/sig apps
312     List mProtectedNetworks;
313 
ConnectivityService(Context context, INetworkManagementService netd, INetworkStatsService statsService, INetworkPolicyManager policyManager)314     public ConnectivityService(Context context, INetworkManagementService netd,
315             INetworkStatsService statsService, INetworkPolicyManager policyManager) {
316         if (DBG) log("ConnectivityService starting up");
317 
318         HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
319         handlerThread.start();
320         mHandler = new MyHandler(handlerThread.getLooper());
321 
322         // setup our unique device name
323         if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
324             String id = Settings.Secure.getString(context.getContentResolver(),
325                     Settings.Secure.ANDROID_ID);
326             if (id != null && id.length() > 0) {
327                 String name = new String("android-").concat(id);
328                 SystemProperties.set("net.hostname", name);
329             }
330         }
331 
332         // read our default dns server ip
333         String dns = Settings.Secure.getString(context.getContentResolver(),
334                 Settings.Secure.DEFAULT_DNS_SERVER);
335         if (dns == null || dns.length() == 0) {
336             dns = context.getResources().getString(
337                     com.android.internal.R.string.config_default_dns_server);
338         }
339         try {
340             mDefaultDns = NetworkUtils.numericToInetAddress(dns);
341         } catch (IllegalArgumentException e) {
342             loge("Error setting defaultDns using " + dns);
343         }
344 
345         mContext = checkNotNull(context, "missing Context");
346         mNetd = checkNotNull(netd, "missing INetworkManagementService");
347         mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
348 
349         try {
350             mPolicyManager.registerListener(mPolicyListener);
351         } catch (RemoteException e) {
352             // ouch, no rules updates means some processes may never get network
353             loge("unable to register INetworkPolicyListener" + e.toString());
354         }
355 
356         final PowerManager powerManager = (PowerManager) context.getSystemService(
357                 Context.POWER_SERVICE);
358         mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
359         mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
360                 com.android.internal.R.integer.config_networkTransitionTimeout);
361 
362         mNetTrackers = new NetworkStateTracker[
363                 ConnectivityManager.MAX_NETWORK_TYPE+1];
364         mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
365 
366         mNetworkPreference = getPersistedNetworkPreference();
367 
368         mRadioAttributes = new RadioAttributes[ConnectivityManager.MAX_RADIO_TYPE+1];
369         mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
370 
371         // Load device network attributes from resources
372         String[] raStrings = context.getResources().getStringArray(
373                 com.android.internal.R.array.radioAttributes);
374         for (String raString : raStrings) {
375             RadioAttributes r = new RadioAttributes(raString);
376             if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {
377                 loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);
378                 continue;
379             }
380             if (mRadioAttributes[r.mType] != null) {
381                 loge("Error in radioAttributes - ignoring attempt to redefine type " +
382                         r.mType);
383                 continue;
384             }
385             mRadioAttributes[r.mType] = r;
386         }
387 
388         String[] naStrings = context.getResources().getStringArray(
389                 com.android.internal.R.array.networkAttributes);
390         for (String naString : naStrings) {
391             try {
392                 NetworkConfig n = new NetworkConfig(naString);
393                 if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
394                     loge("Error in networkAttributes - ignoring attempt to define type " +
395                             n.type);
396                     continue;
397                 }
398                 if (mNetConfigs[n.type] != null) {
399                     loge("Error in networkAttributes - ignoring attempt to redefine type " +
400                             n.type);
401                     continue;
402                 }
403                 if (mRadioAttributes[n.radio] == null) {
404                     loge("Error in networkAttributes - ignoring attempt to use undefined " +
405                             "radio " + n.radio + " in network type " + n.type);
406                     continue;
407                 }
408                 mNetConfigs[n.type] = n;
409                 mNetworksDefined++;
410             } catch(Exception e) {
411                 // ignore it - leave the entry null
412             }
413         }
414 
415         mProtectedNetworks = new ArrayList<Integer>();
416         int[] protectedNetworks = context.getResources().getIntArray(
417                 com.android.internal.R.array.config_protectedNetworks);
418         for (int p : protectedNetworks) {
419             if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
420                 mProtectedNetworks.add(p);
421             } else {
422                 if (DBG) loge("Ignoring protectedNetwork " + p);
423             }
424         }
425 
426         // high priority first
427         mPriorityList = new int[mNetworksDefined];
428         {
429             int insertionPoint = mNetworksDefined-1;
430             int currentLowest = 0;
431             int nextLowest = 0;
432             while (insertionPoint > -1) {
433                 for (NetworkConfig na : mNetConfigs) {
434                     if (na == null) continue;
435                     if (na.priority < currentLowest) continue;
436                     if (na.priority > currentLowest) {
437                         if (na.priority < nextLowest || nextLowest == 0) {
438                             nextLowest = na.priority;
439                         }
440                         continue;
441                     }
442                     mPriorityList[insertionPoint--] = na.type;
443                 }
444                 currentLowest = nextLowest;
445                 nextLowest = 0;
446             }
447         }
448 
449         mNetRequestersPids = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE+1];
450         for (int i : mPriorityList) {
451             mNetRequestersPids[i] = new ArrayList();
452         }
453 
454         mFeatureUsers = new ArrayList<FeatureUser>();
455 
456         mNumDnsEntries = 0;
457 
458         mTestMode = SystemProperties.get("cm.test.mode").equals("true")
459                 && SystemProperties.get("ro.build.type").equals("eng");
460         /*
461          * Create the network state trackers for Wi-Fi and mobile
462          * data. Maybe this could be done with a factory class,
463          * but it's not clear that it's worth it, given that
464          * the number of different network types is not going
465          * to change very often.
466          */
467         for (int netType : mPriorityList) {
468             switch (mNetConfigs[netType].radio) {
469             case ConnectivityManager.TYPE_WIFI:
470                 mNetTrackers[netType] = new WifiStateTracker(netType,
471                         mNetConfigs[netType].name);
472                 mNetTrackers[netType].startMonitoring(context, mHandler);
473                break;
474             case ConnectivityManager.TYPE_MOBILE:
475                 mNetTrackers[netType] = new MobileDataStateTracker(netType,
476                         mNetConfigs[netType].name);
477                 mNetTrackers[netType].startMonitoring(context, mHandler);
478                 break;
479             case ConnectivityManager.TYPE_DUMMY:
480                 mNetTrackers[netType] = new DummyDataStateTracker(netType,
481                         mNetConfigs[netType].name);
482                 mNetTrackers[netType].startMonitoring(context, mHandler);
483                 break;
484             case ConnectivityManager.TYPE_BLUETOOTH:
485                 mNetTrackers[netType] = BluetoothTetheringDataTracker.getInstance();
486                 mNetTrackers[netType].startMonitoring(context, mHandler);
487                 break;
488             case ConnectivityManager.TYPE_ETHERNET:
489                 mNetTrackers[netType] = EthernetDataTracker.getInstance();
490                 mNetTrackers[netType].startMonitoring(context, mHandler);
491                 break;
492             default:
493                 loge("Trying to create a DataStateTracker for an unknown radio type " +
494                         mNetConfigs[netType].radio);
495                 continue;
496             }
497             mCurrentLinkProperties[netType] = null;
498             if (mNetConfigs[netType].isDefault()) mNetTrackers[netType].reconnect();
499         }
500 
501         IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
502         INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
503 
504         mTethering = new Tethering(mContext, nmService, statsService, mHandler.getLooper());
505         mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
506                                   mTethering.getTetherableWifiRegexs().length != 0 ||
507                                   mTethering.getTetherableBluetoothRegexs().length != 0) &&
508                                  mTethering.getUpstreamIfaceTypes().length != 0);
509 
510         mVpn = new Vpn(mContext, new VpnCallback());
511 
512         try {
513             nmService.registerObserver(mTethering);
514             nmService.registerObserver(mVpn);
515         } catch (RemoteException e) {
516             loge("Error registering observer :" + e);
517         }
518 
519         if (DBG) {
520             mInetLog = new ArrayList();
521         }
522 
523         mSettingsObserver = new SettingsObserver(mHandler, EVENT_APPLY_GLOBAL_HTTP_PROXY);
524         mSettingsObserver.observe(mContext);
525 
526         loadGlobalProxy();
527     }
528 
529     /**
530      * Sets the preferred network.
531      * @param preference the new preference
532      */
setNetworkPreference(int preference)533     public void setNetworkPreference(int preference) {
534         enforceChangePermission();
535 
536         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_NETWORK_PREFERENCE, preference, 0));
537     }
538 
getNetworkPreference()539     public int getNetworkPreference() {
540         enforceAccessPermission();
541         int preference;
542         synchronized(this) {
543             preference = mNetworkPreference;
544         }
545         return preference;
546     }
547 
handleSetNetworkPreference(int preference)548     private void handleSetNetworkPreference(int preference) {
549         if (ConnectivityManager.isNetworkTypeValid(preference) &&
550                 mNetConfigs[preference] != null &&
551                 mNetConfigs[preference].isDefault()) {
552             if (mNetworkPreference != preference) {
553                 final ContentResolver cr = mContext.getContentResolver();
554                 Settings.Secure.putInt(cr, Settings.Secure.NETWORK_PREFERENCE, preference);
555                 synchronized(this) {
556                     mNetworkPreference = preference;
557                 }
558                 enforcePreference();
559             }
560         }
561     }
562 
getConnectivityChangeDelay()563     private int getConnectivityChangeDelay() {
564         final ContentResolver cr = mContext.getContentResolver();
565 
566         /** Check system properties for the default value then use secure settings value, if any. */
567         int defaultDelay = SystemProperties.getInt(
568                 "conn." + Settings.Secure.CONNECTIVITY_CHANGE_DELAY,
569                 Settings.Secure.CONNECTIVITY_CHANGE_DELAY_DEFAULT);
570         return Settings.Secure.getInt(cr, Settings.Secure.CONNECTIVITY_CHANGE_DELAY,
571                 defaultDelay);
572     }
573 
getPersistedNetworkPreference()574     private int getPersistedNetworkPreference() {
575         final ContentResolver cr = mContext.getContentResolver();
576 
577         final int networkPrefSetting = Settings.Secure
578                 .getInt(cr, Settings.Secure.NETWORK_PREFERENCE, -1);
579         if (networkPrefSetting != -1) {
580             return networkPrefSetting;
581         }
582 
583         return ConnectivityManager.DEFAULT_NETWORK_PREFERENCE;
584     }
585 
586     /**
587      * Make the state of network connectivity conform to the preference settings
588      * In this method, we only tear down a non-preferred network. Establishing
589      * a connection to the preferred network is taken care of when we handle
590      * the disconnect event from the non-preferred network
591      * (see {@link #handleDisconnect(NetworkInfo)}).
592      */
enforcePreference()593     private void enforcePreference() {
594         if (mNetTrackers[mNetworkPreference].getNetworkInfo().isConnected())
595             return;
596 
597         if (!mNetTrackers[mNetworkPreference].isAvailable())
598             return;
599 
600         for (int t=0; t <= ConnectivityManager.MAX_RADIO_TYPE; t++) {
601             if (t != mNetworkPreference && mNetTrackers[t] != null &&
602                     mNetTrackers[t].getNetworkInfo().isConnected()) {
603                 if (DBG) {
604                     log("tearing down " + mNetTrackers[t].getNetworkInfo() +
605                             " in enforcePreference");
606                 }
607                 teardown(mNetTrackers[t]);
608             }
609         }
610     }
611 
teardown(NetworkStateTracker netTracker)612     private boolean teardown(NetworkStateTracker netTracker) {
613         if (netTracker.teardown()) {
614             netTracker.setTeardownRequested(true);
615             return true;
616         } else {
617             return false;
618         }
619     }
620 
621     /**
622      * Check if UID should be blocked from using the network represented by the
623      * given {@link NetworkStateTracker}.
624      */
isNetworkBlocked(NetworkStateTracker tracker, int uid)625     private boolean isNetworkBlocked(NetworkStateTracker tracker, int uid) {
626         final String iface = tracker.getLinkProperties().getInterfaceName();
627 
628         final boolean networkCostly;
629         final int uidRules;
630         synchronized (mRulesLock) {
631             networkCostly = mMeteredIfaces.contains(iface);
632             uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
633         }
634 
635         if (networkCostly && (uidRules & RULE_REJECT_METERED) != 0) {
636             return true;
637         }
638 
639         // no restrictive rules; network is visible
640         return false;
641     }
642 
643     /**
644      * Return a filtered {@link NetworkInfo}, potentially marked
645      * {@link DetailedState#BLOCKED} based on
646      * {@link #isNetworkBlocked(NetworkStateTracker, int)}.
647      */
getFilteredNetworkInfo(NetworkStateTracker tracker, int uid)648     private NetworkInfo getFilteredNetworkInfo(NetworkStateTracker tracker, int uid) {
649         NetworkInfo info = tracker.getNetworkInfo();
650         if (isNetworkBlocked(tracker, uid)) {
651             // network is blocked; clone and override state
652             info = new NetworkInfo(info);
653             info.setDetailedState(DetailedState.BLOCKED, null, null);
654         }
655         return info;
656     }
657 
658     /**
659      * Return NetworkInfo for the active (i.e., connected) network interface.
660      * It is assumed that at most one network is active at a time. If more
661      * than one is active, it is indeterminate which will be returned.
662      * @return the info for the active network, or {@code null} if none is
663      * active
664      */
665     @Override
getActiveNetworkInfo()666     public NetworkInfo getActiveNetworkInfo() {
667         enforceAccessPermission();
668         final int uid = Binder.getCallingUid();
669         return getNetworkInfo(mActiveDefaultNetwork, uid);
670     }
671 
672     @Override
getActiveNetworkInfoForUid(int uid)673     public NetworkInfo getActiveNetworkInfoForUid(int uid) {
674         enforceConnectivityInternalPermission();
675         return getNetworkInfo(mActiveDefaultNetwork, uid);
676     }
677 
678     @Override
getNetworkInfo(int networkType)679     public NetworkInfo getNetworkInfo(int networkType) {
680         enforceAccessPermission();
681         final int uid = Binder.getCallingUid();
682         return getNetworkInfo(networkType, uid);
683     }
684 
getNetworkInfo(int networkType, int uid)685     private NetworkInfo getNetworkInfo(int networkType, int uid) {
686         NetworkInfo info = null;
687         if (isNetworkTypeValid(networkType)) {
688             final NetworkStateTracker tracker = mNetTrackers[networkType];
689             if (tracker != null) {
690                 info = getFilteredNetworkInfo(tracker, uid);
691             }
692         }
693         return info;
694     }
695 
696     @Override
getAllNetworkInfo()697     public NetworkInfo[] getAllNetworkInfo() {
698         enforceAccessPermission();
699         final int uid = Binder.getCallingUid();
700         final ArrayList<NetworkInfo> result = Lists.newArrayList();
701         synchronized (mRulesLock) {
702             for (NetworkStateTracker tracker : mNetTrackers) {
703                 if (tracker != null) {
704                     result.add(getFilteredNetworkInfo(tracker, uid));
705                 }
706             }
707         }
708         return result.toArray(new NetworkInfo[result.size()]);
709     }
710 
711     @Override
isNetworkSupported(int networkType)712     public boolean isNetworkSupported(int networkType) {
713         enforceAccessPermission();
714         return (isNetworkTypeValid(networkType) && (mNetTrackers[networkType] != null));
715     }
716 
717     /**
718      * Return LinkProperties for the active (i.e., connected) default
719      * network interface.  It is assumed that at most one default network
720      * is active at a time. If more than one is active, it is indeterminate
721      * which will be returned.
722      * @return the ip properties for the active network, or {@code null} if
723      * none is active
724      */
725     @Override
getActiveLinkProperties()726     public LinkProperties getActiveLinkProperties() {
727         return getLinkProperties(mActiveDefaultNetwork);
728     }
729 
730     @Override
getLinkProperties(int networkType)731     public LinkProperties getLinkProperties(int networkType) {
732         enforceAccessPermission();
733         if (isNetworkTypeValid(networkType)) {
734             final NetworkStateTracker tracker = mNetTrackers[networkType];
735             if (tracker != null) {
736                 return tracker.getLinkProperties();
737             }
738         }
739         return null;
740     }
741 
742     @Override
getAllNetworkState()743     public NetworkState[] getAllNetworkState() {
744         enforceAccessPermission();
745         final int uid = Binder.getCallingUid();
746         final ArrayList<NetworkState> result = Lists.newArrayList();
747         synchronized (mRulesLock) {
748             for (NetworkStateTracker tracker : mNetTrackers) {
749                 if (tracker != null) {
750                     final NetworkInfo info = getFilteredNetworkInfo(tracker, uid);
751                     result.add(new NetworkState(
752                             info, tracker.getLinkProperties(), tracker.getLinkCapabilities()));
753                 }
754             }
755         }
756         return result.toArray(new NetworkState[result.size()]);
757     }
758 
getNetworkStateUnchecked(int networkType)759     private NetworkState getNetworkStateUnchecked(int networkType) {
760         if (isNetworkTypeValid(networkType)) {
761             final NetworkStateTracker tracker = mNetTrackers[networkType];
762             if (tracker != null) {
763                 return new NetworkState(tracker.getNetworkInfo(), tracker.getLinkProperties(),
764                         tracker.getLinkCapabilities());
765             }
766         }
767         return null;
768     }
769 
770     @Override
getActiveNetworkQuotaInfo()771     public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
772         enforceAccessPermission();
773         final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
774         if (state != null) {
775             try {
776                 return mPolicyManager.getNetworkQuotaInfo(state);
777             } catch (RemoteException e) {
778             }
779         }
780         return null;
781     }
782 
setRadios(boolean turnOn)783     public boolean setRadios(boolean turnOn) {
784         boolean result = true;
785         enforceChangePermission();
786         for (NetworkStateTracker t : mNetTrackers) {
787             if (t != null) result = t.setRadio(turnOn) && result;
788         }
789         return result;
790     }
791 
setRadio(int netType, boolean turnOn)792     public boolean setRadio(int netType, boolean turnOn) {
793         enforceChangePermission();
794         if (!ConnectivityManager.isNetworkTypeValid(netType)) {
795             return false;
796         }
797         NetworkStateTracker tracker = mNetTrackers[netType];
798         return tracker != null && tracker.setRadio(turnOn);
799     }
800 
801     /**
802      * Used to notice when the calling process dies so we can self-expire
803      *
804      * Also used to know if the process has cleaned up after itself when
805      * our auto-expire timer goes off.  The timer has a link to an object.
806      *
807      */
808     private class FeatureUser implements IBinder.DeathRecipient {
809         int mNetworkType;
810         String mFeature;
811         IBinder mBinder;
812         int mPid;
813         int mUid;
814         long mCreateTime;
815 
FeatureUser(int type, String feature, IBinder binder)816         FeatureUser(int type, String feature, IBinder binder) {
817             super();
818             mNetworkType = type;
819             mFeature = feature;
820             mBinder = binder;
821             mPid = getCallingPid();
822             mUid = getCallingUid();
823             mCreateTime = System.currentTimeMillis();
824 
825             try {
826                 mBinder.linkToDeath(this, 0);
827             } catch (RemoteException e) {
828                 binderDied();
829             }
830         }
831 
unlinkDeathRecipient()832         void unlinkDeathRecipient() {
833             mBinder.unlinkToDeath(this, 0);
834         }
835 
binderDied()836         public void binderDied() {
837             log("ConnectivityService FeatureUser binderDied(" +
838                     mNetworkType + ", " + mFeature + ", " + mBinder + "), created " +
839                     (System.currentTimeMillis() - mCreateTime) + " mSec ago");
840             stopUsingNetworkFeature(this, false);
841         }
842 
expire()843         public void expire() {
844             if (VDBG) {
845                 log("ConnectivityService FeatureUser expire(" +
846                         mNetworkType + ", " + mFeature + ", " + mBinder +"), created " +
847                         (System.currentTimeMillis() - mCreateTime) + " mSec ago");
848             }
849             stopUsingNetworkFeature(this, false);
850         }
851 
isSameUser(FeatureUser u)852         public boolean isSameUser(FeatureUser u) {
853             if (u == null) return false;
854 
855             return isSameUser(u.mPid, u.mUid, u.mNetworkType, u.mFeature);
856         }
857 
isSameUser(int pid, int uid, int networkType, String feature)858         public boolean isSameUser(int pid, int uid, int networkType, String feature) {
859             if ((mPid == pid) && (mUid == uid) && (mNetworkType == networkType) &&
860                 TextUtils.equals(mFeature, feature)) {
861                 return true;
862             }
863             return false;
864         }
865 
toString()866         public String toString() {
867             return "FeatureUser("+mNetworkType+","+mFeature+","+mPid+","+mUid+"), created " +
868                     (System.currentTimeMillis() - mCreateTime) + " mSec ago";
869         }
870     }
871 
872     // javadoc from interface
startUsingNetworkFeature(int networkType, String feature, IBinder binder)873     public int startUsingNetworkFeature(int networkType, String feature,
874             IBinder binder) {
875         if (VDBG) {
876             log("startUsingNetworkFeature for net " + networkType + ": " + feature);
877         }
878         enforceChangePermission();
879         if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
880                 mNetConfigs[networkType] == null) {
881             return Phone.APN_REQUEST_FAILED;
882         }
883 
884         FeatureUser f = new FeatureUser(networkType, feature, binder);
885 
886         // TODO - move this into individual networktrackers
887         int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
888 
889         if (mProtectedNetworks.contains(usedNetworkType)) {
890             enforceConnectivityInternalPermission();
891         }
892 
893         NetworkStateTracker network = mNetTrackers[usedNetworkType];
894         if (network != null) {
895             Integer currentPid = new Integer(getCallingPid());
896             if (usedNetworkType != networkType) {
897                 NetworkInfo ni = network.getNetworkInfo();
898 
899                 if (ni.isAvailable() == false) {
900                     if (DBG) log("special network not available");
901                     if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
902                         return Phone.APN_TYPE_NOT_AVAILABLE;
903                     } else {
904                         // else make the attempt anyway - probably giving REQUEST_STARTED below
905                     }
906                 }
907 
908                 int restoreTimer = getRestoreDefaultNetworkDelay(usedNetworkType);
909 
910                 synchronized(this) {
911                     boolean addToList = true;
912                     if (restoreTimer < 0) {
913                         // In case there is no timer is specified for the feature,
914                         // make sure we don't add duplicate entry with the same request.
915                         for (FeatureUser u : mFeatureUsers) {
916                             if (u.isSameUser(f)) {
917                                 // Duplicate user is found. Do not add.
918                                 addToList = false;
919                                 break;
920                             }
921                         }
922                     }
923 
924                     if (addToList) mFeatureUsers.add(f);
925                     if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
926                         // this gets used for per-pid dns when connected
927                         mNetRequestersPids[usedNetworkType].add(currentPid);
928                     }
929                 }
930 
931                 if (restoreTimer >= 0) {
932                     mHandler.sendMessageDelayed(
933                             mHandler.obtainMessage(EVENT_RESTORE_DEFAULT_NETWORK, f), restoreTimer);
934                 }
935 
936                 if ((ni.isConnectedOrConnecting() == true) &&
937                         !network.isTeardownRequested()) {
938                     if (ni.isConnected() == true) {
939                         // add the pid-specific dns
940                         handleDnsConfigurationChange(usedNetworkType);
941                         if (VDBG) log("special network already active");
942                         return Phone.APN_ALREADY_ACTIVE;
943                     }
944                     if (VDBG) log("special network already connecting");
945                     return Phone.APN_REQUEST_STARTED;
946                 }
947 
948                 // check if the radio in play can make another contact
949                 // assume if cannot for now
950 
951                 if (DBG) {
952                     log("startUsingNetworkFeature reconnecting to " + networkType + ": " + feature);
953                 }
954                 network.reconnect();
955                 return Phone.APN_REQUEST_STARTED;
956             } else {
957                 // need to remember this unsupported request so we respond appropriately on stop
958                 synchronized(this) {
959                     mFeatureUsers.add(f);
960                     if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
961                         // this gets used for per-pid dns when connected
962                         mNetRequestersPids[usedNetworkType].add(currentPid);
963                     }
964                 }
965                 return -1;
966             }
967         }
968         return Phone.APN_TYPE_NOT_AVAILABLE;
969     }
970 
971     // javadoc from interface
stopUsingNetworkFeature(int networkType, String feature)972     public int stopUsingNetworkFeature(int networkType, String feature) {
973         enforceChangePermission();
974 
975         int pid = getCallingPid();
976         int uid = getCallingUid();
977 
978         FeatureUser u = null;
979         boolean found = false;
980 
981         synchronized(this) {
982             for (FeatureUser x : mFeatureUsers) {
983                 if (x.isSameUser(pid, uid, networkType, feature)) {
984                     u = x;
985                     found = true;
986                     break;
987                 }
988             }
989         }
990         if (found && u != null) {
991             // stop regardless of how many other time this proc had called start
992             return stopUsingNetworkFeature(u, true);
993         } else {
994             // none found!
995             if (VDBG) log("stopUsingNetworkFeature - not a live request, ignoring");
996             return 1;
997         }
998     }
999 
stopUsingNetworkFeature(FeatureUser u, boolean ignoreDups)1000     private int stopUsingNetworkFeature(FeatureUser u, boolean ignoreDups) {
1001         int networkType = u.mNetworkType;
1002         String feature = u.mFeature;
1003         int pid = u.mPid;
1004         int uid = u.mUid;
1005 
1006         NetworkStateTracker tracker = null;
1007         boolean callTeardown = false;  // used to carry our decision outside of sync block
1008 
1009         if (VDBG) {
1010             log("stopUsingNetworkFeature: net " + networkType + ": " + feature);
1011         }
1012 
1013         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
1014             if (DBG) {
1015                 log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
1016                         ", net is invalid");
1017             }
1018             return -1;
1019         }
1020 
1021         // need to link the mFeatureUsers list with the mNetRequestersPids state in this
1022         // sync block
1023         synchronized(this) {
1024             // check if this process still has an outstanding start request
1025             if (!mFeatureUsers.contains(u)) {
1026                 if (VDBG) {
1027                     log("stopUsingNetworkFeature: this process has no outstanding requests" +
1028                         ", ignoring");
1029                 }
1030                 return 1;
1031             }
1032             u.unlinkDeathRecipient();
1033             mFeatureUsers.remove(mFeatureUsers.indexOf(u));
1034             // If we care about duplicate requests, check for that here.
1035             //
1036             // This is done to support the extension of a request - the app
1037             // can request we start the network feature again and renew the
1038             // auto-shutoff delay.  Normal "stop" calls from the app though
1039             // do not pay attention to duplicate requests - in effect the
1040             // API does not refcount and a single stop will counter multiple starts.
1041             if (ignoreDups == false) {
1042                 for (FeatureUser x : mFeatureUsers) {
1043                     if (x.isSameUser(u)) {
1044                         if (VDBG) log("stopUsingNetworkFeature: dup is found, ignoring");
1045                         return 1;
1046                     }
1047                 }
1048             }
1049 
1050             // TODO - move to individual network trackers
1051             int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
1052 
1053             tracker =  mNetTrackers[usedNetworkType];
1054             if (tracker == null) {
1055                 if (DBG) {
1056                     log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
1057                             " no known tracker for used net type " + usedNetworkType);
1058                 }
1059                 return -1;
1060             }
1061             if (usedNetworkType != networkType) {
1062                 Integer currentPid = new Integer(pid);
1063                 mNetRequestersPids[usedNetworkType].remove(currentPid);
1064                 reassessPidDns(pid, true);
1065                 if (mNetRequestersPids[usedNetworkType].size() != 0) {
1066                     if (VDBG) {
1067                         log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
1068                                 " others still using it");
1069                     }
1070                     return 1;
1071                 }
1072                 callTeardown = true;
1073             } else {
1074                 if (DBG) {
1075                     log("stopUsingNetworkFeature: net " + networkType + ": " + feature +
1076                             " not a known feature - dropping");
1077                 }
1078             }
1079         }
1080 
1081         if (callTeardown) {
1082             if (DBG) {
1083                 log("stopUsingNetworkFeature: teardown net " + networkType + ": " + feature);
1084             }
1085             tracker.teardown();
1086             return 1;
1087         } else {
1088             return -1;
1089         }
1090     }
1091 
1092     /**
1093      * @deprecated use requestRouteToHostAddress instead
1094      *
1095      * Ensure that a network route exists to deliver traffic to the specified
1096      * host via the specified network interface.
1097      * @param networkType the type of the network over which traffic to the
1098      * specified host is to be routed
1099      * @param hostAddress the IP address of the host to which the route is
1100      * desired
1101      * @return {@code true} on success, {@code false} on failure
1102      */
requestRouteToHost(int networkType, int hostAddress)1103     public boolean requestRouteToHost(int networkType, int hostAddress) {
1104         InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
1105 
1106         if (inetAddress == null) {
1107             return false;
1108         }
1109 
1110         return requestRouteToHostAddress(networkType, inetAddress.getAddress());
1111     }
1112 
1113     /**
1114      * Ensure that a network route exists to deliver traffic to the specified
1115      * host via the specified network interface.
1116      * @param networkType the type of the network over which traffic to the
1117      * specified host is to be routed
1118      * @param hostAddress the IP address of the host to which the route is
1119      * desired
1120      * @return {@code true} on success, {@code false} on failure
1121      */
requestRouteToHostAddress(int networkType, byte[] hostAddress)1122     public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
1123         enforceChangePermission();
1124         if (mProtectedNetworks.contains(networkType)) {
1125             enforceConnectivityInternalPermission();
1126         }
1127 
1128         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
1129             return false;
1130         }
1131         NetworkStateTracker tracker = mNetTrackers[networkType];
1132 
1133         if (tracker == null || !tracker.getNetworkInfo().isConnected() ||
1134                 tracker.isTeardownRequested()) {
1135             if (VDBG) {
1136                 log("requestRouteToHostAddress on down network " +
1137                            "(" + networkType + ") - dropped");
1138             }
1139             return false;
1140         }
1141         try {
1142             InetAddress addr = InetAddress.getByAddress(hostAddress);
1143             LinkProperties lp = tracker.getLinkProperties();
1144             return addRouteToAddress(lp, addr);
1145         } catch (UnknownHostException e) {}
1146         return false;
1147     }
1148 
addRoute(LinkProperties p, RouteInfo r)1149     private boolean addRoute(LinkProperties p, RouteInfo r) {
1150         return modifyRoute(p.getInterfaceName(), p, r, 0, true);
1151     }
1152 
removeRoute(LinkProperties p, RouteInfo r)1153     private boolean removeRoute(LinkProperties p, RouteInfo r) {
1154         return modifyRoute(p.getInterfaceName(), p, r, 0, false);
1155     }
1156 
addRouteToAddress(LinkProperties lp, InetAddress addr)1157     private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
1158         return modifyRouteToAddress(lp, addr, true);
1159     }
1160 
removeRouteToAddress(LinkProperties lp, InetAddress addr)1161     private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
1162         return modifyRouteToAddress(lp, addr, false);
1163     }
1164 
modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd)1165     private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) {
1166         RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr);
1167         if (bestRoute == null) {
1168             bestRoute = RouteInfo.makeHostRoute(addr);
1169         } else {
1170             if (bestRoute.getGateway().equals(addr)) {
1171                 // if there is no better route, add the implied hostroute for our gateway
1172                 bestRoute = RouteInfo.makeHostRoute(addr);
1173             } else {
1174                 // if we will connect to this through another route, add a direct route
1175                 // to it's gateway
1176                 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway());
1177             }
1178         }
1179         return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd);
1180     }
1181 
modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount, boolean doAdd)1182     private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
1183             boolean doAdd) {
1184         if ((ifaceName == null) || (lp == null) || (r == null)) return false;
1185 
1186         if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
1187             loge("Error adding route - too much recursion");
1188             return false;
1189         }
1190 
1191         if (r.isHostRoute() == false) {
1192             RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), r.getGateway());
1193             if (bestRoute != null) {
1194                 if (bestRoute.getGateway().equals(r.getGateway())) {
1195                     // if there is no better route, add the implied hostroute for our gateway
1196                     bestRoute = RouteInfo.makeHostRoute(r.getGateway());
1197                 } else {
1198                     // if we will connect to our gateway through another route, add a direct
1199                     // route to it's gateway
1200                     bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
1201                 }
1202                 modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd);
1203             }
1204         }
1205         if (doAdd) {
1206             if (VDBG) log("Adding " + r + " for interface " + ifaceName);
1207             mAddedRoutes.add(r);
1208             try {
1209                 mNetd.addRoute(ifaceName, r);
1210             } catch (Exception e) {
1211                 // never crash - catch them all
1212                 if (VDBG) loge("Exception trying to add a route: " + e);
1213                 return false;
1214             }
1215         } else {
1216             // if we remove this one and there are no more like it, then refcount==0 and
1217             // we can remove it from the table
1218             mAddedRoutes.remove(r);
1219             if (mAddedRoutes.contains(r) == false) {
1220                 if (VDBG) log("Removing " + r + " for interface " + ifaceName);
1221                 try {
1222                     mNetd.removeRoute(ifaceName, r);
1223                 } catch (Exception e) {
1224                     // never crash - catch them all
1225                     if (VDBG) loge("Exception trying to remove a route: " + e);
1226                     return false;
1227                 }
1228             } else {
1229                 if (VDBG) log("not removing " + r + " as it's still in use");
1230             }
1231         }
1232         return true;
1233     }
1234 
1235     /**
1236      * @see ConnectivityManager#getMobileDataEnabled()
1237      */
getMobileDataEnabled()1238     public boolean getMobileDataEnabled() {
1239         // TODO: This detail should probably be in DataConnectionTracker's
1240         //       which is where we store the value and maybe make this
1241         //       asynchronous.
1242         enforceAccessPermission();
1243         boolean retVal = Settings.Secure.getInt(mContext.getContentResolver(),
1244                 Settings.Secure.MOBILE_DATA, 1) == 1;
1245         if (VDBG) log("getMobileDataEnabled returning " + retVal);
1246         return retVal;
1247     }
1248 
setDataDependency(int networkType, boolean met)1249     public void setDataDependency(int networkType, boolean met) {
1250         enforceConnectivityInternalPermission();
1251 
1252         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_DEPENDENCY_MET,
1253                 (met ? ENABLED : DISABLED), networkType));
1254     }
1255 
handleSetDependencyMet(int networkType, boolean met)1256     private void handleSetDependencyMet(int networkType, boolean met) {
1257         if (mNetTrackers[networkType] != null) {
1258             if (DBG) {
1259                 log("handleSetDependencyMet(" + networkType + ", " + met + ")");
1260             }
1261             mNetTrackers[networkType].setDependencyMet(met);
1262         }
1263     }
1264 
1265     private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
1266         @Override
1267         public void onUidRulesChanged(int uid, int uidRules) {
1268             // only someone like NPMS should only be calling us
1269             mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1270 
1271             if (LOGD_RULES) {
1272                 log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
1273             }
1274 
1275             synchronized (mRulesLock) {
1276                 // skip update when we've already applied rules
1277                 final int oldRules = mUidRules.get(uid, RULE_ALLOW_ALL);
1278                 if (oldRules == uidRules) return;
1279 
1280                 mUidRules.put(uid, uidRules);
1281             }
1282 
1283             // TODO: dispatch into NMS to push rules towards kernel module
1284             // TODO: notify UID when it has requested targeted updates
1285         }
1286 
1287         @Override
1288         public void onMeteredIfacesChanged(String[] meteredIfaces) {
1289             // only someone like NPMS should only be calling us
1290             mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1291 
1292             if (LOGD_RULES) {
1293                 log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
1294             }
1295 
1296             synchronized (mRulesLock) {
1297                 mMeteredIfaces.clear();
1298                 for (String iface : meteredIfaces) {
1299                     mMeteredIfaces.add(iface);
1300                 }
1301             }
1302         }
1303     };
1304 
1305     /**
1306      * @see ConnectivityManager#setMobileDataEnabled(boolean)
1307      */
setMobileDataEnabled(boolean enabled)1308     public void setMobileDataEnabled(boolean enabled) {
1309         enforceChangePermission();
1310         if (DBG) log("setMobileDataEnabled(" + enabled + ")");
1311 
1312         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA,
1313                 (enabled ? ENABLED : DISABLED), 0));
1314     }
1315 
handleSetMobileData(boolean enabled)1316     private void handleSetMobileData(boolean enabled) {
1317         if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) {
1318             if (VDBG) {
1319                 log(mNetTrackers[ConnectivityManager.TYPE_MOBILE].toString() + enabled);
1320             }
1321             mNetTrackers[ConnectivityManager.TYPE_MOBILE].setUserDataEnable(enabled);
1322         }
1323     }
1324 
1325     @Override
setPolicyDataEnable(int networkType, boolean enabled)1326     public void setPolicyDataEnable(int networkType, boolean enabled) {
1327         // only someone like NPMS should only be calling us
1328         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
1329 
1330         mHandler.sendMessage(mHandler.obtainMessage(
1331                 EVENT_SET_POLICY_DATA_ENABLE, networkType, (enabled ? ENABLED : DISABLED)));
1332     }
1333 
handleSetPolicyDataEnable(int networkType, boolean enabled)1334     private void handleSetPolicyDataEnable(int networkType, boolean enabled) {
1335         if (isNetworkTypeValid(networkType)) {
1336             final NetworkStateTracker tracker = mNetTrackers[networkType];
1337             if (tracker != null) {
1338                 tracker.setPolicyDataEnable(enabled);
1339             }
1340         }
1341     }
1342 
enforceAccessPermission()1343     private void enforceAccessPermission() {
1344         mContext.enforceCallingOrSelfPermission(
1345                 android.Manifest.permission.ACCESS_NETWORK_STATE,
1346                 "ConnectivityService");
1347     }
1348 
enforceChangePermission()1349     private void enforceChangePermission() {
1350         mContext.enforceCallingOrSelfPermission(
1351                 android.Manifest.permission.CHANGE_NETWORK_STATE,
1352                 "ConnectivityService");
1353     }
1354 
1355     // TODO Make this a special check when it goes public
enforceTetherChangePermission()1356     private void enforceTetherChangePermission() {
1357         mContext.enforceCallingOrSelfPermission(
1358                 android.Manifest.permission.CHANGE_NETWORK_STATE,
1359                 "ConnectivityService");
1360     }
1361 
enforceTetherAccessPermission()1362     private void enforceTetherAccessPermission() {
1363         mContext.enforceCallingOrSelfPermission(
1364                 android.Manifest.permission.ACCESS_NETWORK_STATE,
1365                 "ConnectivityService");
1366     }
1367 
enforceConnectivityInternalPermission()1368     private void enforceConnectivityInternalPermission() {
1369         mContext.enforceCallingOrSelfPermission(
1370                 android.Manifest.permission.CONNECTIVITY_INTERNAL,
1371                 "ConnectivityService");
1372     }
1373 
1374     /**
1375      * Handle a {@code DISCONNECTED} event. If this pertains to the non-active
1376      * network, we ignore it. If it is for the active network, we send out a
1377      * broadcast. But first, we check whether it might be possible to connect
1378      * to a different network.
1379      * @param info the {@code NetworkInfo} for the network
1380      */
handleDisconnect(NetworkInfo info)1381     private void handleDisconnect(NetworkInfo info) {
1382 
1383         int prevNetType = info.getType();
1384 
1385         mNetTrackers[prevNetType].setTeardownRequested(false);
1386         /*
1387          * If the disconnected network is not the active one, then don't report
1388          * this as a loss of connectivity. What probably happened is that we're
1389          * getting the disconnect for a network that we explicitly disabled
1390          * in accordance with network preference policies.
1391          */
1392         if (!mNetConfigs[prevNetType].isDefault()) {
1393             List pids = mNetRequestersPids[prevNetType];
1394             for (int i = 0; i<pids.size(); i++) {
1395                 Integer pid = (Integer)pids.get(i);
1396                 // will remove them because the net's no longer connected
1397                 // need to do this now as only now do we know the pids and
1398                 // can properly null things that are no longer referenced.
1399                 reassessPidDns(pid.intValue(), false);
1400             }
1401         }
1402 
1403         Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
1404         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
1405         if (info.isFailover()) {
1406             intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
1407             info.setFailover(false);
1408         }
1409         if (info.getReason() != null) {
1410             intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
1411         }
1412         if (info.getExtraInfo() != null) {
1413             intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
1414                     info.getExtraInfo());
1415         }
1416 
1417         if (mNetConfigs[prevNetType].isDefault()) {
1418             tryFailover(prevNetType);
1419             if (mActiveDefaultNetwork != -1) {
1420                 NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
1421                 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
1422             } else {
1423                 mDefaultInetConditionPublished = 0; // we're not connected anymore
1424                 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
1425             }
1426         }
1427         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
1428 
1429         // Reset interface if no other connections are using the same interface
1430         boolean doReset = true;
1431         LinkProperties linkProperties = mNetTrackers[prevNetType].getLinkProperties();
1432         if (linkProperties != null) {
1433             String oldIface = linkProperties.getInterfaceName();
1434             if (TextUtils.isEmpty(oldIface) == false) {
1435                 for (NetworkStateTracker networkStateTracker : mNetTrackers) {
1436                     if (networkStateTracker == null) continue;
1437                     NetworkInfo networkInfo = networkStateTracker.getNetworkInfo();
1438                     if (networkInfo.isConnected() && networkInfo.getType() != prevNetType) {
1439                         LinkProperties l = networkStateTracker.getLinkProperties();
1440                         if (l == null) continue;
1441                         if (oldIface.equals(l.getInterfaceName())) {
1442                             doReset = false;
1443                             break;
1444                         }
1445                     }
1446                 }
1447             }
1448         }
1449 
1450         // do this before we broadcast the change
1451         handleConnectivityChange(prevNetType, doReset);
1452 
1453         final Intent immediateIntent = new Intent(intent);
1454         immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
1455         sendStickyBroadcast(immediateIntent);
1456         sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
1457         /*
1458          * If the failover network is already connected, then immediately send
1459          * out a followup broadcast indicating successful failover
1460          */
1461         if (mActiveDefaultNetwork != -1) {
1462             sendConnectedBroadcastDelayed(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo(),
1463                     getConnectivityChangeDelay());
1464         }
1465     }
1466 
tryFailover(int prevNetType)1467     private void tryFailover(int prevNetType) {
1468         /*
1469          * If this is a default network, check if other defaults are available.
1470          * Try to reconnect on all available and let them hash it out when
1471          * more than one connects.
1472          */
1473         if (mNetConfigs[prevNetType].isDefault()) {
1474             if (mActiveDefaultNetwork == prevNetType) {
1475                 mActiveDefaultNetwork = -1;
1476             }
1477 
1478             // don't signal a reconnect for anything lower or equal priority than our
1479             // current connected default
1480             // TODO - don't filter by priority now - nice optimization but risky
1481 //            int currentPriority = -1;
1482 //            if (mActiveDefaultNetwork != -1) {
1483 //                currentPriority = mNetConfigs[mActiveDefaultNetwork].mPriority;
1484 //            }
1485             for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
1486                 if (checkType == prevNetType) continue;
1487                 if (mNetConfigs[checkType] == null) continue;
1488                 if (!mNetConfigs[checkType].isDefault()) continue;
1489 
1490 // Enabling the isAvailable() optimization caused mobile to not get
1491 // selected if it was in the middle of error handling. Specifically
1492 // a moble connection that took 30 seconds to complete the DEACTIVATE_DATA_CALL
1493 // would not be available and we wouldn't get connected to anything.
1494 // So removing the isAvailable() optimization below for now. TODO: This
1495 // optimization should work and we need to investigate why it doesn't work.
1496 // This could be related to how DEACTIVATE_DATA_CALL is reporting its
1497 // complete before it is really complete.
1498 //                if (!mNetTrackers[checkType].isAvailable()) continue;
1499 
1500 //                if (currentPriority >= mNetConfigs[checkType].mPriority) continue;
1501 
1502                 NetworkStateTracker checkTracker = mNetTrackers[checkType];
1503                 NetworkInfo checkInfo = checkTracker.getNetworkInfo();
1504                 if (!checkInfo.isConnectedOrConnecting() || checkTracker.isTeardownRequested()) {
1505                     checkInfo.setFailover(true);
1506                     checkTracker.reconnect();
1507                 }
1508                 if (DBG) log("Attempting to switch to " + checkInfo.getTypeName());
1509             }
1510         }
1511     }
1512 
sendConnectedBroadcast(NetworkInfo info)1513     private void sendConnectedBroadcast(NetworkInfo info) {
1514         sendGeneralBroadcast(info, CONNECTIVITY_ACTION_IMMEDIATE);
1515         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
1516     }
1517 
sendConnectedBroadcastDelayed(NetworkInfo info, int delayMs)1518     private void sendConnectedBroadcastDelayed(NetworkInfo info, int delayMs) {
1519         sendGeneralBroadcast(info, CONNECTIVITY_ACTION_IMMEDIATE);
1520         sendGeneralBroadcastDelayed(info, CONNECTIVITY_ACTION, delayMs);
1521     }
1522 
sendInetConditionBroadcast(NetworkInfo info)1523     private void sendInetConditionBroadcast(NetworkInfo info) {
1524         sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
1525     }
1526 
makeGeneralIntent(NetworkInfo info, String bcastType)1527     private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
1528         Intent intent = new Intent(bcastType);
1529         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
1530         if (info.isFailover()) {
1531             intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
1532             info.setFailover(false);
1533         }
1534         if (info.getReason() != null) {
1535             intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
1536         }
1537         if (info.getExtraInfo() != null) {
1538             intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
1539                     info.getExtraInfo());
1540         }
1541         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
1542         return intent;
1543     }
1544 
sendGeneralBroadcast(NetworkInfo info, String bcastType)1545     private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
1546         sendStickyBroadcast(makeGeneralIntent(info, bcastType));
1547     }
1548 
sendGeneralBroadcastDelayed(NetworkInfo info, String bcastType, int delayMs)1549     private void sendGeneralBroadcastDelayed(NetworkInfo info, String bcastType, int delayMs) {
1550         sendStickyBroadcastDelayed(makeGeneralIntent(info, bcastType), delayMs);
1551     }
1552 
1553     /**
1554      * Called when an attempt to fail over to another network has failed.
1555      * @param info the {@link NetworkInfo} for the failed network
1556      */
handleConnectionFailure(NetworkInfo info)1557     private void handleConnectionFailure(NetworkInfo info) {
1558         mNetTrackers[info.getType()].setTeardownRequested(false);
1559 
1560         String reason = info.getReason();
1561         String extraInfo = info.getExtraInfo();
1562 
1563         String reasonText;
1564         if (reason == null) {
1565             reasonText = ".";
1566         } else {
1567             reasonText = " (" + reason + ").";
1568         }
1569         loge("Attempt to connect to " + info.getTypeName() + " failed" + reasonText);
1570 
1571         Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
1572         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
1573         if (getActiveNetworkInfo() == null) {
1574             intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
1575         }
1576         if (reason != null) {
1577             intent.putExtra(ConnectivityManager.EXTRA_REASON, reason);
1578         }
1579         if (extraInfo != null) {
1580             intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, extraInfo);
1581         }
1582         if (info.isFailover()) {
1583             intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
1584             info.setFailover(false);
1585         }
1586 
1587         if (mNetConfigs[info.getType()].isDefault()) {
1588             tryFailover(info.getType());
1589             if (mActiveDefaultNetwork != -1) {
1590                 NetworkInfo switchTo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
1591                 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
1592             } else {
1593                 mDefaultInetConditionPublished = 0;
1594                 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
1595             }
1596         }
1597 
1598         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
1599 
1600         final Intent immediateIntent = new Intent(intent);
1601         immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
1602         sendStickyBroadcast(immediateIntent);
1603         sendStickyBroadcast(intent);
1604         /*
1605          * If the failover network is already connected, then immediately send
1606          * out a followup broadcast indicating successful failover
1607          */
1608         if (mActiveDefaultNetwork != -1) {
1609             sendConnectedBroadcast(mNetTrackers[mActiveDefaultNetwork].getNetworkInfo());
1610         }
1611     }
1612 
sendStickyBroadcast(Intent intent)1613     private void sendStickyBroadcast(Intent intent) {
1614         synchronized(this) {
1615             if (!mSystemReady) {
1616                 mInitialBroadcast = new Intent(intent);
1617             }
1618             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
1619             if (VDBG) {
1620                 log("sendStickyBroadcast: action=" + intent.getAction());
1621             }
1622 
1623             mContext.sendStickyBroadcast(intent);
1624         }
1625     }
1626 
sendStickyBroadcastDelayed(Intent intent, int delayMs)1627     private void sendStickyBroadcastDelayed(Intent intent, int delayMs) {
1628         if (delayMs <= 0) {
1629             sendStickyBroadcast(intent);
1630         } else {
1631             if (VDBG) {
1632                 log("sendStickyBroadcastDelayed: delayMs=" + delayMs + ", action="
1633                         + intent.getAction());
1634             }
1635             mHandler.sendMessageDelayed(mHandler.obtainMessage(
1636                     EVENT_SEND_STICKY_BROADCAST_INTENT, intent), delayMs);
1637         }
1638     }
1639 
systemReady()1640     void systemReady() {
1641         synchronized(this) {
1642             mSystemReady = true;
1643             if (mInitialBroadcast != null) {
1644                 mContext.sendStickyBroadcast(mInitialBroadcast);
1645                 mInitialBroadcast = null;
1646             }
1647         }
1648         // load the global proxy at startup
1649         mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY));
1650     }
1651 
handleConnect(NetworkInfo info)1652     private void handleConnect(NetworkInfo info) {
1653         final int type = info.getType();
1654 
1655         // snapshot isFailover, because sendConnectedBroadcast() resets it
1656         boolean isFailover = info.isFailover();
1657         final NetworkStateTracker thisNet = mNetTrackers[type];
1658 
1659         // if this is a default net and other default is running
1660         // kill the one not preferred
1661         if (mNetConfigs[type].isDefault()) {
1662             if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
1663                 if ((type != mNetworkPreference &&
1664                         mNetConfigs[mActiveDefaultNetwork].priority >
1665                         mNetConfigs[type].priority) ||
1666                         mNetworkPreference == mActiveDefaultNetwork) {
1667                         // don't accept this one
1668                         if (VDBG) {
1669                             log("Not broadcasting CONNECT_ACTION " +
1670                                 "to torn down network " + info.getTypeName());
1671                         }
1672                         teardown(thisNet);
1673                         return;
1674                 } else {
1675                     // tear down the other
1676                     NetworkStateTracker otherNet =
1677                             mNetTrackers[mActiveDefaultNetwork];
1678                     if (DBG) {
1679                         log("Policy requires " + otherNet.getNetworkInfo().getTypeName() +
1680                             " teardown");
1681                     }
1682                     if (!teardown(otherNet)) {
1683                         loge("Network declined teardown request");
1684                         teardown(thisNet);
1685                         return;
1686                     }
1687                 }
1688             }
1689             synchronized (ConnectivityService.this) {
1690                 // have a new default network, release the transition wakelock in a second
1691                 // if it's held.  The second pause is to allow apps to reconnect over the
1692                 // new network
1693                 if (mNetTransitionWakeLock.isHeld()) {
1694                     mHandler.sendMessageDelayed(mHandler.obtainMessage(
1695                             EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
1696                             mNetTransitionWakeLockSerialNumber, 0),
1697                             1000);
1698                 }
1699             }
1700             mActiveDefaultNetwork = type;
1701             // this will cause us to come up initially as unconnected and switching
1702             // to connected after our normal pause unless somebody reports us as reall
1703             // disconnected
1704             mDefaultInetConditionPublished = 0;
1705             mDefaultConnectionSequence++;
1706             mInetConditionChangeInFlight = false;
1707             // Don't do this - if we never sign in stay, grey
1708             //reportNetworkCondition(mActiveDefaultNetwork, 100);
1709         }
1710         thisNet.setTeardownRequested(false);
1711         updateNetworkSettings(thisNet);
1712         handleConnectivityChange(type, false);
1713         sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
1714 
1715         // notify battery stats service about this network
1716         final String iface = thisNet.getLinkProperties().getInterfaceName();
1717         if (iface != null) {
1718             try {
1719                 BatteryStatsService.getService().noteNetworkInterfaceType(iface, type);
1720             } catch (RemoteException e) {
1721                 // ignored; service lives in system_server
1722             }
1723         }
1724     }
1725 
1726     /**
1727      * After a change in the connectivity state of a network. We're mainly
1728      * concerned with making sure that the list of DNS servers is set up
1729      * according to which networks are connected, and ensuring that the
1730      * right routing table entries exist.
1731      */
handleConnectivityChange(int netType, boolean doReset)1732     private void handleConnectivityChange(int netType, boolean doReset) {
1733         int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0;
1734 
1735         /*
1736          * If a non-default network is enabled, add the host routes that
1737          * will allow it's DNS servers to be accessed.
1738          */
1739         handleDnsConfigurationChange(netType);
1740 
1741         LinkProperties curLp = mCurrentLinkProperties[netType];
1742         LinkProperties newLp = null;
1743 
1744         if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
1745             newLp = mNetTrackers[netType].getLinkProperties();
1746             if (VDBG) {
1747                 log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
1748                         " doReset=" + doReset + " resetMask=" + resetMask +
1749                         "\n   curLp=" + curLp +
1750                         "\n   newLp=" + newLp);
1751             }
1752 
1753             if (curLp != null) {
1754                 if (curLp.isIdenticalInterfaceName(newLp)) {
1755                     CompareResult<LinkAddress> car = curLp.compareAddresses(newLp);
1756                     if ((car.removed.size() != 0) || (car.added.size() != 0)) {
1757                         for (LinkAddress linkAddr : car.removed) {
1758                             if (linkAddr.getAddress() instanceof Inet4Address) {
1759                                 resetMask |= NetworkUtils.RESET_IPV4_ADDRESSES;
1760                             }
1761                             if (linkAddr.getAddress() instanceof Inet6Address) {
1762                                 resetMask |= NetworkUtils.RESET_IPV6_ADDRESSES;
1763                             }
1764                         }
1765                         if (DBG) {
1766                             log("handleConnectivityChange: addresses changed" +
1767                                     " linkProperty[" + netType + "]:" + " resetMask=" + resetMask +
1768                                     "\n   car=" + car);
1769                         }
1770                     } else {
1771                         if (DBG) {
1772                             log("handleConnectivityChange: address are the same reset per doReset" +
1773                                    " linkProperty[" + netType + "]:" +
1774                                    " resetMask=" + resetMask);
1775                         }
1776                     }
1777                 } else {
1778                     resetMask = NetworkUtils.RESET_ALL_ADDRESSES;
1779                     if (DBG) {
1780                         log("handleConnectivityChange: interface not not equivalent reset both" +
1781                                 " linkProperty[" + netType + "]:" +
1782                                 " resetMask=" + resetMask);
1783                     }
1784                 }
1785             }
1786             if (mNetConfigs[netType].isDefault()) {
1787                 handleApplyDefaultProxy(newLp.getHttpProxy());
1788             }
1789         } else {
1790             if (VDBG) {
1791                 log("handleConnectivityChange: changed linkProperty[" + netType + "]:" +
1792                         " doReset=" + doReset + " resetMask=" + resetMask +
1793                         "\n  curLp=" + curLp +
1794                         "\n  newLp= null");
1795             }
1796         }
1797         mCurrentLinkProperties[netType] = newLp;
1798         boolean resetDns = updateRoutes(newLp, curLp, mNetConfigs[netType].isDefault());
1799 
1800         if (resetMask != 0 || resetDns) {
1801             LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
1802             if (linkProperties != null) {
1803                 String iface = linkProperties.getInterfaceName();
1804                 if (TextUtils.isEmpty(iface) == false) {
1805                     if (resetMask != 0) {
1806                         if (DBG) log("resetConnections(" + iface + ", " + resetMask + ")");
1807                         NetworkUtils.resetConnections(iface, resetMask);
1808 
1809                         // Tell VPN the interface is down. It is a temporary
1810                         // but effective fix to make VPN aware of the change.
1811                         if ((resetMask & NetworkUtils.RESET_IPV4_ADDRESSES) != 0) {
1812                             mVpn.interfaceStatusChanged(iface, false);
1813                         }
1814                     }
1815                     if (resetDns) {
1816                         if (VDBG) log("resetting DNS cache for " + iface);
1817                         try {
1818                             mNetd.flushInterfaceDnsCache(iface);
1819                         } catch (Exception e) {
1820                             // never crash - catch them all
1821                             if (DBG) loge("Exception resetting dns cache: " + e);
1822                         }
1823                     }
1824                 }
1825             }
1826         }
1827 
1828         // TODO: Temporary notifying upstread change to Tethering.
1829         //       @see bug/4455071
1830         /** Notify TetheringService if interface name has been changed. */
1831         if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
1832                              Phone.REASON_LINK_PROPERTIES_CHANGED)) {
1833             if (isTetheringSupported()) {
1834                 mTethering.handleTetherIfaceChange();
1835             }
1836         }
1837     }
1838 
1839     /**
1840      * Add and remove routes using the old properties (null if not previously connected),
1841      * new properties (null if becoming disconnected).  May even be double null, which
1842      * is a noop.
1843      * Uses isLinkDefault to determine if default routes should be set or conversely if
1844      * host routes should be set to the dns servers
1845      * returns a boolean indicating the routes changed
1846      */
updateRoutes(LinkProperties newLp, LinkProperties curLp, boolean isLinkDefault)1847     private boolean updateRoutes(LinkProperties newLp, LinkProperties curLp,
1848             boolean isLinkDefault) {
1849         Collection<RouteInfo> routesToAdd = null;
1850         CompareResult<InetAddress> dnsDiff = new CompareResult<InetAddress>();
1851         CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
1852         if (curLp != null) {
1853             // check for the delta between the current set and the new
1854             routeDiff = curLp.compareRoutes(newLp);
1855             dnsDiff = curLp.compareDnses(newLp);
1856         } else if (newLp != null) {
1857             routeDiff.added = newLp.getRoutes();
1858             dnsDiff.added = newLp.getDnses();
1859         }
1860 
1861         boolean routesChanged = (routeDiff.removed.size() != 0 || routeDiff.added.size() != 0);
1862 
1863         for (RouteInfo r : routeDiff.removed) {
1864             if (isLinkDefault || ! r.isDefaultRoute()) {
1865                 removeRoute(curLp, r);
1866             }
1867         }
1868 
1869         for (RouteInfo r :  routeDiff.added) {
1870             if (isLinkDefault || ! r.isDefaultRoute()) {
1871                 addRoute(newLp, r);
1872             } else {
1873                 // many radios add a default route even when we don't want one.
1874                 // remove the default route unless somebody else has asked for it
1875                 String ifaceName = newLp.getInterfaceName();
1876                 if (TextUtils.isEmpty(ifaceName) == false && mAddedRoutes.contains(r) == false) {
1877                     if (VDBG) log("Removing " + r + " for interface " + ifaceName);
1878                     try {
1879                         mNetd.removeRoute(ifaceName, r);
1880                     } catch (Exception e) {
1881                         // never crash - catch them all
1882                         if (VDBG) loge("Exception trying to remove a route: " + e);
1883                     }
1884                 }
1885             }
1886         }
1887 
1888         if (!isLinkDefault) {
1889             // handle DNS routes
1890             if (routesChanged) {
1891                 // routes changed - remove all old dns entries and add new
1892                 if (curLp != null) {
1893                     for (InetAddress oldDns : curLp.getDnses()) {
1894                         removeRouteToAddress(curLp, oldDns);
1895                     }
1896                 }
1897                 if (newLp != null) {
1898                     for (InetAddress newDns : newLp.getDnses()) {
1899                         addRouteToAddress(newLp, newDns);
1900                     }
1901                 }
1902             } else {
1903                 // no change in routes, check for change in dns themselves
1904                 for (InetAddress oldDns : dnsDiff.removed) {
1905                     removeRouteToAddress(curLp, oldDns);
1906                 }
1907                 for (InetAddress newDns : dnsDiff.added) {
1908                     addRouteToAddress(newLp, newDns);
1909                 }
1910             }
1911         }
1912         return routesChanged;
1913     }
1914 
1915 
1916    /**
1917      * Reads the network specific TCP buffer sizes from SystemProperties
1918      * net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
1919      * wide use
1920      */
updateNetworkSettings(NetworkStateTracker nt)1921    public void updateNetworkSettings(NetworkStateTracker nt) {
1922         String key = nt.getTcpBufferSizesPropName();
1923         String bufferSizes = SystemProperties.get(key);
1924 
1925         if (bufferSizes.length() == 0) {
1926             if (VDBG) log(key + " not found in system properties. Using defaults");
1927 
1928             // Setting to default values so we won't be stuck to previous values
1929             key = "net.tcp.buffersize.default";
1930             bufferSizes = SystemProperties.get(key);
1931         }
1932 
1933         // Set values in kernel
1934         if (bufferSizes.length() != 0) {
1935             if (VDBG) {
1936                 log("Setting TCP values: [" + bufferSizes
1937                         + "] which comes from [" + key + "]");
1938             }
1939             setBufferSize(bufferSizes);
1940         }
1941     }
1942 
1943    /**
1944      * Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
1945      * which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
1946      *
1947      * @param bufferSizes in the format of "readMin, readInitial, readMax,
1948      *        writeMin, writeInitial, writeMax"
1949      */
setBufferSize(String bufferSizes)1950     private void setBufferSize(String bufferSizes) {
1951         try {
1952             String[] values = bufferSizes.split(",");
1953 
1954             if (values.length == 6) {
1955               final String prefix = "/sys/kernel/ipv4/tcp_";
1956                 FileUtils.stringToFile(prefix + "rmem_min", values[0]);
1957                 FileUtils.stringToFile(prefix + "rmem_def", values[1]);
1958                 FileUtils.stringToFile(prefix + "rmem_max", values[2]);
1959                 FileUtils.stringToFile(prefix + "wmem_min", values[3]);
1960                 FileUtils.stringToFile(prefix + "wmem_def", values[4]);
1961                 FileUtils.stringToFile(prefix + "wmem_max", values[5]);
1962             } else {
1963                 loge("Invalid buffersize string: " + bufferSizes);
1964             }
1965         } catch (IOException e) {
1966             loge("Can't set tcp buffer sizes:" + e);
1967         }
1968     }
1969 
1970     /**
1971      * Adjust the per-process dns entries (net.dns<x>.<pid>) based
1972      * on the highest priority active net which this process requested.
1973      * If there aren't any, clear it out
1974      */
reassessPidDns(int myPid, boolean doBump)1975     private void reassessPidDns(int myPid, boolean doBump)
1976     {
1977         if (VDBG) log("reassessPidDns for pid " + myPid);
1978         for(int i : mPriorityList) {
1979             if (mNetConfigs[i].isDefault()) {
1980                 continue;
1981             }
1982             NetworkStateTracker nt = mNetTrackers[i];
1983             if (nt.getNetworkInfo().isConnected() &&
1984                     !nt.isTeardownRequested()) {
1985                 LinkProperties p = nt.getLinkProperties();
1986                 if (p == null) continue;
1987                 List pids = mNetRequestersPids[i];
1988                 for (int j=0; j<pids.size(); j++) {
1989                     Integer pid = (Integer)pids.get(j);
1990                     if (pid.intValue() == myPid) {
1991                         Collection<InetAddress> dnses = p.getDnses();
1992                         writePidDns(dnses, myPid);
1993                         if (doBump) {
1994                             bumpDns();
1995                         }
1996                         return;
1997                     }
1998                 }
1999            }
2000         }
2001         // nothing found - delete
2002         for (int i = 1; ; i++) {
2003             String prop = "net.dns" + i + "." + myPid;
2004             if (SystemProperties.get(prop).length() == 0) {
2005                 if (doBump) {
2006                     bumpDns();
2007                 }
2008                 return;
2009             }
2010             SystemProperties.set(prop, "");
2011         }
2012     }
2013 
2014     // return true if results in a change
writePidDns(Collection <InetAddress> dnses, int pid)2015     private boolean writePidDns(Collection <InetAddress> dnses, int pid) {
2016         int j = 1;
2017         boolean changed = false;
2018         for (InetAddress dns : dnses) {
2019             String dnsString = dns.getHostAddress();
2020             if (changed || !dnsString.equals(SystemProperties.get("net.dns" + j + "." + pid))) {
2021                 changed = true;
2022                 SystemProperties.set("net.dns" + j++ + "." + pid, dns.getHostAddress());
2023             }
2024         }
2025         return changed;
2026     }
2027 
bumpDns()2028     private void bumpDns() {
2029         /*
2030          * Bump the property that tells the name resolver library to reread
2031          * the DNS server list from the properties.
2032          */
2033         String propVal = SystemProperties.get("net.dnschange");
2034         int n = 0;
2035         if (propVal.length() != 0) {
2036             try {
2037                 n = Integer.parseInt(propVal);
2038             } catch (NumberFormatException e) {}
2039         }
2040         SystemProperties.set("net.dnschange", "" + (n+1));
2041         /*
2042          * Tell the VMs to toss their DNS caches
2043          */
2044         Intent intent = new Intent(Intent.ACTION_CLEAR_DNS_CACHE);
2045         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
2046         /*
2047          * Connectivity events can happen before boot has completed ...
2048          */
2049         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2050         mContext.sendBroadcast(intent);
2051     }
2052 
2053     // Caller must grab mDnsLock.
updateDns(String network, String iface, Collection<InetAddress> dnses, String domains)2054     private boolean updateDns(String network, String iface,
2055             Collection<InetAddress> dnses, String domains) {
2056         boolean changed = false;
2057         int last = 0;
2058         if (dnses.size() == 0 && mDefaultDns != null) {
2059             ++last;
2060             String value = mDefaultDns.getHostAddress();
2061             if (!value.equals(SystemProperties.get("net.dns1"))) {
2062                 if (DBG) {
2063                     loge("no dns provided for " + network + " - using " + value);
2064                 }
2065                 changed = true;
2066                 SystemProperties.set("net.dns1", value);
2067             }
2068         } else {
2069             for (InetAddress dns : dnses) {
2070                 ++last;
2071                 String key = "net.dns" + last;
2072                 String value = dns.getHostAddress();
2073                 if (!changed && value.equals(SystemProperties.get(key))) {
2074                     continue;
2075                 }
2076                 if (VDBG) {
2077                     log("adding dns " + value + " for " + network);
2078                 }
2079                 changed = true;
2080                 SystemProperties.set(key, value);
2081             }
2082         }
2083         for (int i = last + 1; i <= mNumDnsEntries; ++i) {
2084             String key = "net.dns" + i;
2085             if (VDBG) log("erasing " + key);
2086             changed = true;
2087             SystemProperties.set(key, "");
2088         }
2089         mNumDnsEntries = last;
2090 
2091         if (changed) {
2092             try {
2093                 mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses));
2094                 mNetd.setDefaultInterfaceForDns(iface);
2095             } catch (Exception e) {
2096                 if (VDBG) loge("exception setting default dns interface: " + e);
2097             }
2098         }
2099         if (!domains.equals(SystemProperties.get("net.dns.search"))) {
2100             SystemProperties.set("net.dns.search", domains);
2101             changed = true;
2102         }
2103         return changed;
2104     }
2105 
handleDnsConfigurationChange(int netType)2106     private void handleDnsConfigurationChange(int netType) {
2107         // add default net's dns entries
2108         NetworkStateTracker nt = mNetTrackers[netType];
2109         if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
2110             LinkProperties p = nt.getLinkProperties();
2111             if (p == null) return;
2112             Collection<InetAddress> dnses = p.getDnses();
2113             boolean changed = false;
2114             if (mNetConfigs[netType].isDefault()) {
2115                 String network = nt.getNetworkInfo().getTypeName();
2116                 synchronized (mDnsLock) {
2117                     if (!mDnsOverridden) {
2118                         changed = updateDns(network, p.getInterfaceName(), dnses, "");
2119                     }
2120                 }
2121             } else {
2122                 try {
2123                     mNetd.setDnsServersForInterface(p.getInterfaceName(),
2124                             NetworkUtils.makeStrings(dnses));
2125                 } catch (Exception e) {
2126                     if (VDBG) loge("exception setting dns servers: " + e);
2127                 }
2128                 // set per-pid dns for attached secondary nets
2129                 List pids = mNetRequestersPids[netType];
2130                 for (int y=0; y< pids.size(); y++) {
2131                     Integer pid = (Integer)pids.get(y);
2132                     changed = writePidDns(dnses, pid.intValue());
2133                 }
2134             }
2135             if (changed) bumpDns();
2136         }
2137     }
2138 
getRestoreDefaultNetworkDelay(int networkType)2139     private int getRestoreDefaultNetworkDelay(int networkType) {
2140         String restoreDefaultNetworkDelayStr = SystemProperties.get(
2141                 NETWORK_RESTORE_DELAY_PROP_NAME);
2142         if(restoreDefaultNetworkDelayStr != null &&
2143                 restoreDefaultNetworkDelayStr.length() != 0) {
2144             try {
2145                 return Integer.valueOf(restoreDefaultNetworkDelayStr);
2146             } catch (NumberFormatException e) {
2147             }
2148         }
2149         // if the system property isn't set, use the value for the apn type
2150         int ret = RESTORE_DEFAULT_NETWORK_DELAY;
2151 
2152         if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) &&
2153                 (mNetConfigs[networkType] != null)) {
2154             ret = mNetConfigs[networkType].restoreTime;
2155         }
2156         return ret;
2157     }
2158 
2159     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)2160     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2161         if (mContext.checkCallingOrSelfPermission(
2162                 android.Manifest.permission.DUMP)
2163                 != PackageManager.PERMISSION_GRANTED) {
2164             pw.println("Permission Denial: can't dump ConnectivityService " +
2165                     "from from pid=" + Binder.getCallingPid() + ", uid=" +
2166                     Binder.getCallingUid());
2167             return;
2168         }
2169         pw.println();
2170         for (NetworkStateTracker nst : mNetTrackers) {
2171             if (nst != null) {
2172                 if (nst.getNetworkInfo().isConnected()) {
2173                     pw.println("Active network: " + nst.getNetworkInfo().
2174                             getTypeName());
2175                 }
2176                 pw.println(nst.getNetworkInfo());
2177                 pw.println(nst);
2178                 pw.println();
2179             }
2180         }
2181 
2182         pw.println("Network Requester Pids:");
2183         for (int net : mPriorityList) {
2184             String pidString = net + ": ";
2185             for (Object pid : mNetRequestersPids[net]) {
2186                 pidString = pidString + pid.toString() + ", ";
2187             }
2188             pw.println(pidString);
2189         }
2190         pw.println();
2191 
2192         pw.println("FeatureUsers:");
2193         for (Object requester : mFeatureUsers) {
2194             pw.println(requester.toString());
2195         }
2196         pw.println();
2197 
2198         synchronized (this) {
2199             pw.println("NetworkTranstionWakeLock is currently " +
2200                     (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
2201             pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
2202         }
2203         pw.println();
2204 
2205         mTethering.dump(fd, pw, args);
2206 
2207         if (mInetLog != null) {
2208             pw.println();
2209             pw.println("Inet condition reports:");
2210             for(int i = 0; i < mInetLog.size(); i++) {
2211                 pw.println(mInetLog.get(i));
2212             }
2213         }
2214     }
2215 
2216     // must be stateless - things change under us.
2217     private class MyHandler extends Handler {
MyHandler(Looper looper)2218         public MyHandler(Looper looper) {
2219             super(looper);
2220         }
2221 
2222         @Override
handleMessage(Message msg)2223         public void handleMessage(Message msg) {
2224             NetworkInfo info;
2225             switch (msg.what) {
2226                 case NetworkStateTracker.EVENT_STATE_CHANGED:
2227                     info = (NetworkInfo) msg.obj;
2228                     int type = info.getType();
2229                     NetworkInfo.State state = info.getState();
2230 
2231                     if (VDBG || (state == NetworkInfo.State.CONNECTED) ||
2232                             (state == NetworkInfo.State.DISCONNECTED)) {
2233                         log("ConnectivityChange for " +
2234                             info.getTypeName() + ": " +
2235                             state + "/" + info.getDetailedState());
2236                     }
2237 
2238                     // Connectivity state changed:
2239                     // [31-13] Reserved for future use
2240                     // [12-9] Network subtype (for mobile network, as defined
2241                     //         by TelephonyManager)
2242                     // [8-3] Detailed state ordinal (as defined by
2243                     //         NetworkInfo.DetailedState)
2244                     // [2-0] Network type (as defined by ConnectivityManager)
2245                     int eventLogParam = (info.getType() & 0x7) |
2246                             ((info.getDetailedState().ordinal() & 0x3f) << 3) |
2247                             (info.getSubtype() << 9);
2248                     EventLog.writeEvent(EventLogTags.CONNECTIVITY_STATE_CHANGED,
2249                             eventLogParam);
2250 
2251                     if (info.getDetailedState() ==
2252                             NetworkInfo.DetailedState.FAILED) {
2253                         handleConnectionFailure(info);
2254                     } else if (state == NetworkInfo.State.DISCONNECTED) {
2255                         handleDisconnect(info);
2256                     } else if (state == NetworkInfo.State.SUSPENDED) {
2257                         // TODO: need to think this over.
2258                         // the logic here is, handle SUSPENDED the same as
2259                         // DISCONNECTED. The only difference being we are
2260                         // broadcasting an intent with NetworkInfo that's
2261                         // suspended. This allows the applications an
2262                         // opportunity to handle DISCONNECTED and SUSPENDED
2263                         // differently, or not.
2264                         handleDisconnect(info);
2265                     } else if (state == NetworkInfo.State.CONNECTED) {
2266                         handleConnect(info);
2267                     }
2268                     break;
2269                 case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED:
2270                     info = (NetworkInfo) msg.obj;
2271                     // TODO: Temporary allowing network configuration
2272                     //       change not resetting sockets.
2273                     //       @see bug/4455071
2274                     handleConnectivityChange(info.getType(), false);
2275                     break;
2276                 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
2277                     String causedBy = null;
2278                     synchronized (ConnectivityService.this) {
2279                         if (msg.arg1 == mNetTransitionWakeLockSerialNumber &&
2280                                 mNetTransitionWakeLock.isHeld()) {
2281                             mNetTransitionWakeLock.release();
2282                             causedBy = mNetTransitionWakeLockCausedBy;
2283                         }
2284                     }
2285                     if (causedBy != null) {
2286                         log("NetTransition Wakelock for " + causedBy + " released by timeout");
2287                     }
2288                     break;
2289                 case EVENT_RESTORE_DEFAULT_NETWORK:
2290                     FeatureUser u = (FeatureUser)msg.obj;
2291                     u.expire();
2292                     break;
2293                 case EVENT_INET_CONDITION_CHANGE:
2294                 {
2295                     int netType = msg.arg1;
2296                     int condition = msg.arg2;
2297                     handleInetConditionChange(netType, condition);
2298                     break;
2299                 }
2300                 case EVENT_INET_CONDITION_HOLD_END:
2301                 {
2302                     int netType = msg.arg1;
2303                     int sequence = msg.arg2;
2304                     handleInetConditionHoldEnd(netType, sequence);
2305                     break;
2306                 }
2307                 case EVENT_SET_NETWORK_PREFERENCE:
2308                 {
2309                     int preference = msg.arg1;
2310                     handleSetNetworkPreference(preference);
2311                     break;
2312                 }
2313                 case EVENT_SET_MOBILE_DATA:
2314                 {
2315                     boolean enabled = (msg.arg1 == ENABLED);
2316                     handleSetMobileData(enabled);
2317                     break;
2318                 }
2319                 case EVENT_APPLY_GLOBAL_HTTP_PROXY:
2320                 {
2321                     handleDeprecatedGlobalHttpProxy();
2322                     break;
2323                 }
2324                 case EVENT_SET_DEPENDENCY_MET:
2325                 {
2326                     boolean met = (msg.arg1 == ENABLED);
2327                     handleSetDependencyMet(msg.arg2, met);
2328                     break;
2329                 }
2330                 case EVENT_RESTORE_DNS:
2331                 {
2332                     if (mActiveDefaultNetwork != -1) {
2333                         handleDnsConfigurationChange(mActiveDefaultNetwork);
2334                     }
2335                     break;
2336                 }
2337                 case EVENT_SEND_STICKY_BROADCAST_INTENT:
2338                 {
2339                     Intent intent = (Intent)msg.obj;
2340                     sendStickyBroadcast(intent);
2341                     break;
2342                 }
2343                 case EVENT_SET_POLICY_DATA_ENABLE: {
2344                     final int networkType = msg.arg1;
2345                     final boolean enabled = msg.arg2 == ENABLED;
2346                     handleSetPolicyDataEnable(networkType, enabled);
2347                 }
2348             }
2349         }
2350     }
2351 
2352     // javadoc from interface
tether(String iface)2353     public int tether(String iface) {
2354         enforceTetherChangePermission();
2355 
2356         if (isTetheringSupported()) {
2357             return mTethering.tether(iface);
2358         } else {
2359             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
2360         }
2361     }
2362 
2363     // javadoc from interface
untether(String iface)2364     public int untether(String iface) {
2365         enforceTetherChangePermission();
2366 
2367         if (isTetheringSupported()) {
2368             return mTethering.untether(iface);
2369         } else {
2370             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
2371         }
2372     }
2373 
2374     // javadoc from interface
getLastTetherError(String iface)2375     public int getLastTetherError(String iface) {
2376         enforceTetherAccessPermission();
2377 
2378         if (isTetheringSupported()) {
2379             return mTethering.getLastTetherError(iface);
2380         } else {
2381             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
2382         }
2383     }
2384 
2385     // TODO - proper iface API for selection by property, inspection, etc
getTetherableUsbRegexs()2386     public String[] getTetherableUsbRegexs() {
2387         enforceTetherAccessPermission();
2388         if (isTetheringSupported()) {
2389             return mTethering.getTetherableUsbRegexs();
2390         } else {
2391             return new String[0];
2392         }
2393     }
2394 
getTetherableWifiRegexs()2395     public String[] getTetherableWifiRegexs() {
2396         enforceTetherAccessPermission();
2397         if (isTetheringSupported()) {
2398             return mTethering.getTetherableWifiRegexs();
2399         } else {
2400             return new String[0];
2401         }
2402     }
2403 
getTetherableBluetoothRegexs()2404     public String[] getTetherableBluetoothRegexs() {
2405         enforceTetherAccessPermission();
2406         if (isTetheringSupported()) {
2407             return mTethering.getTetherableBluetoothRegexs();
2408         } else {
2409             return new String[0];
2410         }
2411     }
2412 
setUsbTethering(boolean enable)2413     public int setUsbTethering(boolean enable) {
2414         enforceTetherAccessPermission();
2415         if (isTetheringSupported()) {
2416             return mTethering.setUsbTethering(enable);
2417         } else {
2418             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
2419         }
2420     }
2421 
2422     // TODO - move iface listing, queries, etc to new module
2423     // javadoc from interface
getTetherableIfaces()2424     public String[] getTetherableIfaces() {
2425         enforceTetherAccessPermission();
2426         return mTethering.getTetherableIfaces();
2427     }
2428 
getTetheredIfaces()2429     public String[] getTetheredIfaces() {
2430         enforceTetherAccessPermission();
2431         return mTethering.getTetheredIfaces();
2432     }
2433 
2434     @Override
getTetheredIfacePairs()2435     public String[] getTetheredIfacePairs() {
2436         enforceTetherAccessPermission();
2437         return mTethering.getTetheredIfacePairs();
2438     }
2439 
getTetheringErroredIfaces()2440     public String[] getTetheringErroredIfaces() {
2441         enforceTetherAccessPermission();
2442         return mTethering.getErroredIfaces();
2443     }
2444 
2445     // if ro.tether.denied = true we default to no tethering
2446     // gservices could set the secure setting to 1 though to enable it on a build where it
2447     // had previously been turned off.
isTetheringSupported()2448     public boolean isTetheringSupported() {
2449         enforceTetherAccessPermission();
2450         int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
2451         boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(),
2452                 Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0);
2453         // Short term disabling of Tethering if DUN is required.
2454         // TODO - fix multi-connection tethering using policy-base routing
2455         int[] upstreamConnTypes = mTethering.getUpstreamIfaceTypes();
2456         for (int i : upstreamConnTypes) {
2457             if (i == ConnectivityManager.TYPE_MOBILE_DUN) return false;
2458         }
2459         return tetherEnabledInSettings && mTetheringConfigValid;
2460     }
2461 
2462     // An API NetworkStateTrackers can call when they lose their network.
2463     // This will automatically be cleared after X seconds or a network becomes CONNECTED,
2464     // whichever happens first.  The timer is started by the first caller and not
2465     // restarted by subsequent callers.
requestNetworkTransitionWakelock(String forWhom)2466     public void requestNetworkTransitionWakelock(String forWhom) {
2467         enforceConnectivityInternalPermission();
2468         synchronized (this) {
2469             if (mNetTransitionWakeLock.isHeld()) return;
2470             mNetTransitionWakeLockSerialNumber++;
2471             mNetTransitionWakeLock.acquire();
2472             mNetTransitionWakeLockCausedBy = forWhom;
2473         }
2474         mHandler.sendMessageDelayed(mHandler.obtainMessage(
2475                 EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
2476                 mNetTransitionWakeLockSerialNumber, 0),
2477                 mNetTransitionWakeLockTimeout);
2478         return;
2479     }
2480 
2481     // 100 percent is full good, 0 is full bad.
reportInetCondition(int networkType, int percentage)2482     public void reportInetCondition(int networkType, int percentage) {
2483         if (VDBG) log("reportNetworkCondition(" + networkType + ", " + percentage + ")");
2484         mContext.enforceCallingOrSelfPermission(
2485                 android.Manifest.permission.STATUS_BAR,
2486                 "ConnectivityService");
2487 
2488         if (DBG) {
2489             int pid = getCallingPid();
2490             int uid = getCallingUid();
2491             String s = pid + "(" + uid + ") reports inet is " +
2492                 (percentage > 50 ? "connected" : "disconnected") + " (" + percentage + ") on " +
2493                 "network Type " + networkType + " at " + GregorianCalendar.getInstance().getTime();
2494             mInetLog.add(s);
2495             while(mInetLog.size() > INET_CONDITION_LOG_MAX_SIZE) {
2496                 mInetLog.remove(0);
2497             }
2498         }
2499         mHandler.sendMessage(mHandler.obtainMessage(
2500             EVENT_INET_CONDITION_CHANGE, networkType, percentage));
2501     }
2502 
handleInetConditionChange(int netType, int condition)2503     private void handleInetConditionChange(int netType, int condition) {
2504         if (mActiveDefaultNetwork == -1) {
2505             if (DBG) log("handleInetConditionChange: no active default network - ignore");
2506             return;
2507         }
2508         if (mActiveDefaultNetwork != netType) {
2509             if (DBG) log("handleInetConditionChange: net=" + netType +
2510                             " != default=" + mActiveDefaultNetwork + " - ignore");
2511             return;
2512         }
2513         if (VDBG) {
2514             log("handleInetConditionChange: net=" +
2515                     netType + ", condition=" + condition +
2516                     ",mActiveDefaultNetwork=" + mActiveDefaultNetwork);
2517         }
2518         mDefaultInetCondition = condition;
2519         int delay;
2520         if (mInetConditionChangeInFlight == false) {
2521             if (VDBG) log("handleInetConditionChange: starting a change hold");
2522             // setup a new hold to debounce this
2523             if (mDefaultInetCondition > 50) {
2524                 delay = Settings.Secure.getInt(mContext.getContentResolver(),
2525                         Settings.Secure.INET_CONDITION_DEBOUNCE_UP_DELAY, 500);
2526             } else {
2527                 delay = Settings.Secure.getInt(mContext.getContentResolver(),
2528                 Settings.Secure.INET_CONDITION_DEBOUNCE_DOWN_DELAY, 3000);
2529             }
2530             mInetConditionChangeInFlight = true;
2531             mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_INET_CONDITION_HOLD_END,
2532                     mActiveDefaultNetwork, mDefaultConnectionSequence), delay);
2533         } else {
2534             // we've set the new condition, when this hold ends that will get picked up
2535             if (VDBG) log("handleInetConditionChange: currently in hold - not setting new end evt");
2536         }
2537     }
2538 
handleInetConditionHoldEnd(int netType, int sequence)2539     private void handleInetConditionHoldEnd(int netType, int sequence) {
2540         if (DBG) {
2541             log("handleInetConditionHoldEnd: net=" + netType +
2542                     ", condition=" + mDefaultInetCondition +
2543                     ", published condition=" + mDefaultInetConditionPublished);
2544         }
2545         mInetConditionChangeInFlight = false;
2546 
2547         if (mActiveDefaultNetwork == -1) {
2548             if (DBG) log("handleInetConditionHoldEnd: no active default network - ignoring");
2549             return;
2550         }
2551         if (mDefaultConnectionSequence != sequence) {
2552             if (DBG) log("handleInetConditionHoldEnd: event hold for obsolete network - ignoring");
2553             return;
2554         }
2555         // TODO: Figure out why this optimization sometimes causes a
2556         //       change in mDefaultInetCondition to be missed and the
2557         //       UI to not be updated.
2558         //if (mDefaultInetConditionPublished == mDefaultInetCondition) {
2559         //    if (DBG) log("no change in condition - aborting");
2560         //    return;
2561         //}
2562         NetworkInfo networkInfo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
2563         if (networkInfo.isConnected() == false) {
2564             if (DBG) log("handleInetConditionHoldEnd: default network not connected - ignoring");
2565             return;
2566         }
2567         mDefaultInetConditionPublished = mDefaultInetCondition;
2568         sendInetConditionBroadcast(networkInfo);
2569         return;
2570     }
2571 
getProxy()2572     public ProxyProperties getProxy() {
2573         synchronized (mDefaultProxyLock) {
2574             return mDefaultProxyDisabled ? null : mDefaultProxy;
2575         }
2576     }
2577 
setGlobalProxy(ProxyProperties proxyProperties)2578     public void setGlobalProxy(ProxyProperties proxyProperties) {
2579         enforceChangePermission();
2580         synchronized (mGlobalProxyLock) {
2581             if (proxyProperties == mGlobalProxy) return;
2582             if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
2583             if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
2584 
2585             String host = "";
2586             int port = 0;
2587             String exclList = "";
2588             if (proxyProperties != null && !TextUtils.isEmpty(proxyProperties.getHost())) {
2589                 mGlobalProxy = new ProxyProperties(proxyProperties);
2590                 host = mGlobalProxy.getHost();
2591                 port = mGlobalProxy.getPort();
2592                 exclList = mGlobalProxy.getExclusionList();
2593             } else {
2594                 mGlobalProxy = null;
2595             }
2596             ContentResolver res = mContext.getContentResolver();
2597             Settings.Secure.putString(res, Settings.Secure.GLOBAL_HTTP_PROXY_HOST, host);
2598             Settings.Secure.putInt(res, Settings.Secure.GLOBAL_HTTP_PROXY_PORT, port);
2599             Settings.Secure.putString(res, Settings.Secure.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
2600                     exclList);
2601         }
2602 
2603         if (mGlobalProxy == null) {
2604             proxyProperties = mDefaultProxy;
2605         }
2606         //sendProxyBroadcast(proxyProperties);
2607     }
2608 
loadGlobalProxy()2609     private void loadGlobalProxy() {
2610         ContentResolver res = mContext.getContentResolver();
2611         String host = Settings.Secure.getString(res, Settings.Secure.GLOBAL_HTTP_PROXY_HOST);
2612         int port = Settings.Secure.getInt(res, Settings.Secure.GLOBAL_HTTP_PROXY_PORT, 0);
2613         String exclList = Settings.Secure.getString(res,
2614                 Settings.Secure.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
2615         if (!TextUtils.isEmpty(host)) {
2616             ProxyProperties proxyProperties = new ProxyProperties(host, port, exclList);
2617             synchronized (mGlobalProxyLock) {
2618                 mGlobalProxy = proxyProperties;
2619             }
2620         }
2621     }
2622 
getGlobalProxy()2623     public ProxyProperties getGlobalProxy() {
2624         synchronized (mGlobalProxyLock) {
2625             return mGlobalProxy;
2626         }
2627     }
2628 
handleApplyDefaultProxy(ProxyProperties proxy)2629     private void handleApplyDefaultProxy(ProxyProperties proxy) {
2630         if (proxy != null && TextUtils.isEmpty(proxy.getHost())) {
2631             proxy = null;
2632         }
2633         synchronized (mDefaultProxyLock) {
2634             if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
2635             if (mDefaultProxy == proxy) return;
2636             mDefaultProxy = proxy;
2637 
2638             if (!mDefaultProxyDisabled) {
2639                 sendProxyBroadcast(proxy);
2640             }
2641         }
2642     }
2643 
handleDeprecatedGlobalHttpProxy()2644     private void handleDeprecatedGlobalHttpProxy() {
2645         String proxy = Settings.Secure.getString(mContext.getContentResolver(),
2646                 Settings.Secure.HTTP_PROXY);
2647         if (!TextUtils.isEmpty(proxy)) {
2648             String data[] = proxy.split(":");
2649             String proxyHost =  data[0];
2650             int proxyPort = 8080;
2651             if (data.length > 1) {
2652                 try {
2653                     proxyPort = Integer.parseInt(data[1]);
2654                 } catch (NumberFormatException e) {
2655                     return;
2656                 }
2657             }
2658             ProxyProperties p = new ProxyProperties(data[0], proxyPort, "");
2659             setGlobalProxy(p);
2660         }
2661     }
2662 
sendProxyBroadcast(ProxyProperties proxy)2663     private void sendProxyBroadcast(ProxyProperties proxy) {
2664         if (proxy == null) proxy = new ProxyProperties("", 0, "");
2665         if (DBG) log("sending Proxy Broadcast for " + proxy);
2666         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
2667         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
2668             Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2669         intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
2670         mContext.sendStickyBroadcast(intent);
2671     }
2672 
2673     private static class SettingsObserver extends ContentObserver {
2674         private int mWhat;
2675         private Handler mHandler;
SettingsObserver(Handler handler, int what)2676         SettingsObserver(Handler handler, int what) {
2677             super(handler);
2678             mHandler = handler;
2679             mWhat = what;
2680         }
2681 
observe(Context context)2682         void observe(Context context) {
2683             ContentResolver resolver = context.getContentResolver();
2684             resolver.registerContentObserver(Settings.Secure.getUriFor(
2685                     Settings.Secure.HTTP_PROXY), false, this);
2686         }
2687 
2688         @Override
onChange(boolean selfChange)2689         public void onChange(boolean selfChange) {
2690             mHandler.obtainMessage(mWhat).sendToTarget();
2691         }
2692     }
2693 
log(String s)2694     private void log(String s) {
2695         Slog.d(TAG, s);
2696     }
2697 
loge(String s)2698     private void loge(String s) {
2699         Slog.e(TAG, s);
2700     }
2701 
convertFeatureToNetworkType(int networkType, String feature)2702     int convertFeatureToNetworkType(int networkType, String feature) {
2703         int usedNetworkType = networkType;
2704 
2705         if(networkType == ConnectivityManager.TYPE_MOBILE) {
2706             if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
2707                 usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS;
2708             } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
2709                 usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL;
2710             } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
2711                     TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
2712                 usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN;
2713             } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
2714                 usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
2715             } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_FOTA)) {
2716                 usedNetworkType = ConnectivityManager.TYPE_MOBILE_FOTA;
2717             } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_IMS)) {
2718                 usedNetworkType = ConnectivityManager.TYPE_MOBILE_IMS;
2719             } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_CBS)) {
2720                 usedNetworkType = ConnectivityManager.TYPE_MOBILE_CBS;
2721             } else {
2722                 Slog.e(TAG, "Can't match any mobile netTracker!");
2723             }
2724         } else if (networkType == ConnectivityManager.TYPE_WIFI) {
2725             if (TextUtils.equals(feature, "p2p")) {
2726                 usedNetworkType = ConnectivityManager.TYPE_WIFI_P2P;
2727             } else {
2728                 Slog.e(TAG, "Can't match any wifi netTracker!");
2729             }
2730         } else {
2731             Slog.e(TAG, "Unexpected network type");
2732         }
2733         return usedNetworkType;
2734     }
2735 
checkNotNull(T value, String message)2736     private static <T> T checkNotNull(T value, String message) {
2737         if (value == null) {
2738             throw new NullPointerException(message);
2739         }
2740         return value;
2741     }
2742 
2743     /**
2744      * Protect a socket from VPN routing rules. This method is used by
2745      * VpnBuilder and not available in ConnectivityManager. Permissions
2746      * are checked in Vpn class.
2747      * @hide
2748      */
2749     @Override
protectVpn(ParcelFileDescriptor socket)2750     public boolean protectVpn(ParcelFileDescriptor socket) {
2751         try {
2752             int type = mActiveDefaultNetwork;
2753             if (ConnectivityManager.isNetworkTypeValid(type)) {
2754                 mVpn.protect(socket, mNetTrackers[type].getLinkProperties().getInterfaceName());
2755                 return true;
2756             }
2757         } catch (Exception e) {
2758             // ignore
2759         } finally {
2760             try {
2761                 socket.close();
2762             } catch (Exception e) {
2763                 // ignore
2764             }
2765         }
2766         return false;
2767     }
2768 
2769     /**
2770      * Prepare for a VPN application. This method is used by VpnDialogs
2771      * and not available in ConnectivityManager. Permissions are checked
2772      * in Vpn class.
2773      * @hide
2774      */
2775     @Override
prepareVpn(String oldPackage, String newPackage)2776     public boolean prepareVpn(String oldPackage, String newPackage) {
2777         return mVpn.prepare(oldPackage, newPackage);
2778     }
2779 
2780     /**
2781      * Configure a TUN interface and return its file descriptor. Parameters
2782      * are encoded and opaque to this class. This method is used by VpnBuilder
2783      * and not available in ConnectivityManager. Permissions are checked in
2784      * Vpn class.
2785      * @hide
2786      */
2787     @Override
establishVpn(VpnConfig config)2788     public ParcelFileDescriptor establishVpn(VpnConfig config) {
2789         return mVpn.establish(config);
2790     }
2791 
2792     /**
2793      * Start legacy VPN and return an intent to VpnDialogs. This method is
2794      * used by VpnSettings and not available in ConnectivityManager.
2795      * Permissions are checked in Vpn class.
2796      * @hide
2797      */
2798     @Override
startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd)2799     public void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
2800         mVpn.startLegacyVpn(config, racoon, mtpd);
2801     }
2802 
2803     /**
2804      * Return the information of the ongoing legacy VPN. This method is used
2805      * by VpnSettings and not available in ConnectivityManager. Permissions
2806      * are checked in Vpn class.
2807      * @hide
2808      */
2809     @Override
getLegacyVpnInfo()2810     public LegacyVpnInfo getLegacyVpnInfo() {
2811         return mVpn.getLegacyVpnInfo();
2812     }
2813 
2814     /**
2815      * Callback for VPN subsystem. Currently VPN is not adapted to the service
2816      * through NetworkStateTracker since it works differently. For example, it
2817      * needs to override DNS servers but never takes the default routes. It
2818      * relies on another data network, and it could keep existing connections
2819      * alive after reconnecting, switching between networks, or even resuming
2820      * from deep sleep. Calls from applications should be done synchronously
2821      * to avoid race conditions. As these are all hidden APIs, refactoring can
2822      * be done whenever a better abstraction is developed.
2823      */
2824     public class VpnCallback {
2825 
VpnCallback()2826         private VpnCallback() {
2827         }
2828 
override(List<String> dnsServers, List<String> searchDomains)2829         public void override(List<String> dnsServers, List<String> searchDomains) {
2830             if (dnsServers == null) {
2831                 restore();
2832                 return;
2833             }
2834 
2835             // Convert DNS servers into addresses.
2836             List<InetAddress> addresses = new ArrayList<InetAddress>();
2837             for (String address : dnsServers) {
2838                 // Double check the addresses and remove invalid ones.
2839                 try {
2840                     addresses.add(InetAddress.parseNumericAddress(address));
2841                 } catch (Exception e) {
2842                     // ignore
2843                 }
2844             }
2845             if (addresses.isEmpty()) {
2846                 restore();
2847                 return;
2848             }
2849 
2850             // Concatenate search domains into a string.
2851             StringBuilder buffer = new StringBuilder();
2852             if (searchDomains != null) {
2853                 for (String domain : searchDomains) {
2854                     buffer.append(domain).append(' ');
2855                 }
2856             }
2857             String domains = buffer.toString().trim();
2858 
2859             // Apply DNS changes.
2860             boolean changed = false;
2861             synchronized (mDnsLock) {
2862                 changed = updateDns("VPN", "VPN", addresses, domains);
2863                 mDnsOverridden = true;
2864             }
2865             if (changed) {
2866                 bumpDns();
2867             }
2868 
2869             // Temporarily disable the default proxy.
2870             synchronized (mDefaultProxyLock) {
2871                 mDefaultProxyDisabled = true;
2872                 if (mDefaultProxy != null) {
2873                     sendProxyBroadcast(null);
2874                 }
2875             }
2876 
2877             // TODO: support proxy per network.
2878         }
2879 
restore()2880         public void restore() {
2881             synchronized (mDnsLock) {
2882                 if (mDnsOverridden) {
2883                     mDnsOverridden = false;
2884                     mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
2885                 }
2886             }
2887             synchronized (mDefaultProxyLock) {
2888                 mDefaultProxyDisabled = false;
2889                 if (mDefaultProxy != null) {
2890                     sendProxyBroadcast(mDefaultProxy);
2891                 }
2892             }
2893         }
2894     }
2895 }
2896