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