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