1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; 20 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 21 import static android.net.ConnectivityManager.NETID_UNSET; 22 import static android.net.ConnectivityManager.TYPE_NONE; 23 import static android.net.ConnectivityManager.TYPE_VPN; 24 import static android.net.ConnectivityManager.getNetworkTypeName; 25 import static android.net.ConnectivityManager.isNetworkTypeValid; 26 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; 27 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 28 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; 29 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 30 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 31 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 32 import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED; 33 import static android.net.NetworkPolicyManager.RULE_NONE; 34 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; 35 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 36 import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED; 37 import static android.net.NetworkPolicyManager.uidRulesToString; 38 39 import android.annotation.Nullable; 40 import android.app.BroadcastOptions; 41 import android.app.NotificationManager; 42 import android.app.PendingIntent; 43 import android.content.BroadcastReceiver; 44 import android.content.ContentResolver; 45 import android.content.Context; 46 import android.content.Intent; 47 import android.content.IntentFilter; 48 import android.content.pm.PackageManager; 49 import android.content.res.Configuration; 50 import android.content.res.Resources; 51 import android.database.ContentObserver; 52 import android.net.ConnectivityManager; 53 import android.net.ConnectivityManager.PacketKeepalive; 54 import android.net.IConnectivityManager; 55 import android.net.INetworkManagementEventObserver; 56 import android.net.INetworkPolicyListener; 57 import android.net.INetworkPolicyManager; 58 import android.net.INetworkStatsService; 59 import android.net.LinkProperties; 60 import android.net.LinkProperties.CompareResult; 61 import android.net.Network; 62 import android.net.NetworkAgent; 63 import android.net.NetworkCapabilities; 64 import android.net.NetworkConfig; 65 import android.net.NetworkInfo; 66 import android.net.NetworkInfo.DetailedState; 67 import android.net.NetworkMisc; 68 import android.net.NetworkQuotaInfo; 69 import android.net.NetworkRequest; 70 import android.net.NetworkState; 71 import android.net.NetworkUtils; 72 import android.net.Proxy; 73 import android.net.ProxyInfo; 74 import android.net.RouteInfo; 75 import android.net.UidRange; 76 import android.net.Uri; 77 import android.net.metrics.DefaultNetworkEvent; 78 import android.net.metrics.IpConnectivityLog; 79 import android.net.metrics.NetworkEvent; 80 import android.net.util.AvoidBadWifiTracker; 81 import android.os.Binder; 82 import android.os.Build; 83 import android.os.Bundle; 84 import android.os.FileUtils; 85 import android.os.Handler; 86 import android.os.HandlerThread; 87 import android.os.IBinder; 88 import android.os.INetworkManagementService; 89 import android.os.Looper; 90 import android.os.Message; 91 import android.os.Messenger; 92 import android.os.ParcelFileDescriptor; 93 import android.os.PowerManager; 94 import android.os.Process; 95 import android.os.RemoteException; 96 import android.os.ResultReceiver; 97 import android.os.SystemClock; 98 import android.os.SystemProperties; 99 import android.os.UserHandle; 100 import android.os.UserManager; 101 import android.provider.Settings; 102 import android.security.Credentials; 103 import android.security.KeyStore; 104 import android.telephony.TelephonyManager; 105 import android.text.TextUtils; 106 import android.util.ArraySet; 107 import android.util.LocalLog; 108 import android.util.LocalLog.ReadOnlyLocalLog; 109 import android.util.Log; 110 import android.util.Pair; 111 import android.util.Slog; 112 import android.util.SparseArray; 113 import android.util.SparseBooleanArray; 114 import android.util.SparseIntArray; 115 import android.util.Xml; 116 117 import com.android.internal.R; 118 import com.android.internal.annotations.GuardedBy; 119 import com.android.internal.annotations.VisibleForTesting; 120 import com.android.internal.app.IBatteryStats; 121 import com.android.internal.net.LegacyVpnInfo; 122 import com.android.internal.net.NetworkStatsFactory; 123 import com.android.internal.net.VpnConfig; 124 import com.android.internal.net.VpnInfo; 125 import com.android.internal.net.VpnProfile; 126 import com.android.internal.util.AsyncChannel; 127 import com.android.internal.util.IndentingPrintWriter; 128 import com.android.internal.util.MessageUtils; 129 import com.android.internal.util.WakeupMessage; 130 import com.android.internal.util.XmlUtils; 131 import com.android.server.am.BatteryStatsService; 132 import com.android.server.connectivity.DataConnectionStats; 133 import com.android.server.connectivity.KeepaliveTracker; 134 import com.android.server.connectivity.Nat464Xlat; 135 import com.android.server.connectivity.LingerMonitor; 136 import com.android.server.connectivity.NetworkAgentInfo; 137 import com.android.server.connectivity.NetworkDiagnostics; 138 import com.android.server.connectivity.NetworkMonitor; 139 import com.android.server.connectivity.NetworkNotificationManager; 140 import com.android.server.connectivity.NetworkNotificationManager.NotificationType; 141 import com.android.server.connectivity.PacManager; 142 import com.android.server.connectivity.PermissionMonitor; 143 import com.android.server.connectivity.Tethering; 144 import com.android.server.connectivity.Vpn; 145 import com.android.server.net.BaseNetworkObserver; 146 import com.android.server.net.LockdownVpnTracker; 147 148 import com.google.android.collect.Lists; 149 150 import org.xmlpull.v1.XmlPullParser; 151 import org.xmlpull.v1.XmlPullParserException; 152 153 import java.io.File; 154 import java.io.FileDescriptor; 155 import java.io.FileNotFoundException; 156 import java.io.FileReader; 157 import java.io.IOException; 158 import java.io.PrintWriter; 159 import java.net.Inet4Address; 160 import java.net.InetAddress; 161 import java.net.UnknownHostException; 162 import java.util.ArrayDeque; 163 import java.util.ArrayList; 164 import java.util.Arrays; 165 import java.util.Collection; 166 import java.util.HashMap; 167 import java.util.HashSet; 168 import java.util.List; 169 import java.util.Map; 170 import java.util.Objects; 171 import java.util.SortedSet; 172 import java.util.TreeSet; 173 174 /** 175 * @hide 176 */ 177 public class ConnectivityService extends IConnectivityManager.Stub 178 implements PendingIntent.OnFinished { 179 private static final String TAG = ConnectivityService.class.getSimpleName(); 180 181 private static final boolean DBG = true; 182 private static final boolean VDBG = false; 183 184 private static final boolean LOGD_RULES = false; 185 private static final boolean LOGD_BLOCKED_NETWORKINFO = true; 186 187 // TODO: create better separation between radio types and network types 188 189 // how long to wait before switching back to a radio's default network 190 private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000; 191 // system property that can override the above value 192 private static final String NETWORK_RESTORE_DELAY_PROP_NAME = 193 "android.telephony.apn-restore"; 194 195 // How long to wait before putting up a "This network doesn't have an Internet connection, 196 // connect anyway?" dialog after the user selects a network that doesn't validate. 197 private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000; 198 199 // Default to 30s linger time-out. Modifiable only for testing. 200 private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger"; 201 private static final int DEFAULT_LINGER_DELAY_MS = 30_000; 202 @VisibleForTesting 203 protected int mLingerDelayMs; // Can't be final, or test subclass constructors can't change it. 204 205 // How long to delay to removal of a pending intent based request. 206 // See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS 207 private final int mReleasePendingIntentDelayMs; 208 209 private Tethering mTethering; 210 211 private final PermissionMonitor mPermissionMonitor; 212 213 private KeyStore mKeyStore; 214 215 @GuardedBy("mVpns") 216 private final SparseArray<Vpn> mVpns = new SparseArray<Vpn>(); 217 218 private boolean mLockdownEnabled; 219 private LockdownVpnTracker mLockdownTracker; 220 221 /** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */ 222 private Object mRulesLock = new Object(); 223 /** Currently active network rules by UID. */ 224 @GuardedBy("mRulesLock") 225 private SparseIntArray mUidRules = new SparseIntArray(); 226 /** Set of ifaces that are costly. */ 227 @GuardedBy("mRulesLock") 228 private ArraySet<String> mMeteredIfaces = new ArraySet<>(); 229 /** Flag indicating if background data is restricted. */ 230 @GuardedBy("mRulesLock") 231 private boolean mRestrictBackground; 232 233 final private Context mContext; 234 private int mNetworkPreference; 235 // 0 is full bad, 100 is full good 236 private int mDefaultInetConditionPublished = 0; 237 238 private int mNumDnsEntries; 239 240 private boolean mTestMode; 241 private static ConnectivityService sServiceInstance; 242 243 private INetworkManagementService mNetd; 244 private INetworkStatsService mStatsService; 245 private INetworkPolicyManager mPolicyManager; 246 247 private String mCurrentTcpBufferSizes; 248 249 private static final int ENABLED = 1; 250 private static final int DISABLED = 0; 251 252 private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames( 253 new Class[] { AsyncChannel.class, ConnectivityService.class, NetworkAgent.class, 254 NetworkAgentInfo.class }); 255 256 private enum ReapUnvalidatedNetworks { 257 // Tear down networks that have no chance (e.g. even if validated) of becoming 258 // the highest scoring network satisfying a NetworkRequest. This should be passed when 259 // all networks have been rematched against all NetworkRequests. 260 REAP, 261 // Don't reap networks. This should be passed when some networks have not yet been 262 // rematched against all NetworkRequests. 263 DONT_REAP 264 }; 265 266 /** 267 * used internally to change our mobile data enabled flag 268 */ 269 private static final int EVENT_CHANGE_MOBILE_DATA_ENABLED = 2; 270 271 /** 272 * used internally to clear a wakelock when transitioning 273 * from one net to another. Clear happens when we get a new 274 * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens 275 * after a timeout if no network is found (typically 1 min). 276 */ 277 private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8; 278 279 /** 280 * used internally to reload global proxy settings 281 */ 282 private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9; 283 284 /** 285 * PAC manager has received new port. 286 */ 287 private static final int EVENT_PROXY_HAS_CHANGED = 16; 288 289 /** 290 * used internally when registering NetworkFactories 291 * obj = NetworkFactoryInfo 292 */ 293 private static final int EVENT_REGISTER_NETWORK_FACTORY = 17; 294 295 /** 296 * used internally when registering NetworkAgents 297 * obj = Messenger 298 */ 299 private static final int EVENT_REGISTER_NETWORK_AGENT = 18; 300 301 /** 302 * used to add a network request 303 * includes a NetworkRequestInfo 304 */ 305 private static final int EVENT_REGISTER_NETWORK_REQUEST = 19; 306 307 /** 308 * indicates a timeout period is over - check if we had a network yet or not 309 * and if not, call the timeout callback (but leave the request live until they 310 * cancel it. 311 * includes a NetworkRequestInfo 312 */ 313 private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20; 314 315 /** 316 * used to add a network listener - no request 317 * includes a NetworkRequestInfo 318 */ 319 private static final int EVENT_REGISTER_NETWORK_LISTENER = 21; 320 321 /** 322 * used to remove a network request, either a listener or a real request 323 * arg1 = UID of caller 324 * obj = NetworkRequest 325 */ 326 private static final int EVENT_RELEASE_NETWORK_REQUEST = 22; 327 328 /** 329 * used internally when registering NetworkFactories 330 * obj = Messenger 331 */ 332 private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23; 333 334 /** 335 * used internally to expire a wakelock when transitioning 336 * from one net to another. Expire happens when we fail to find 337 * a new network (typically after 1 minute) - 338 * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found 339 * a replacement network. 340 */ 341 private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24; 342 343 /** 344 * Used internally to indicate the system is ready. 345 */ 346 private static final int EVENT_SYSTEM_READY = 25; 347 348 /** 349 * used to add a network request with a pending intent 350 * obj = NetworkRequestInfo 351 */ 352 private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26; 353 354 /** 355 * used to remove a pending intent and its associated network request. 356 * arg1 = UID of caller 357 * obj = PendingIntent 358 */ 359 private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27; 360 361 /** 362 * used to specify whether a network should be used even if unvalidated. 363 * arg1 = whether to accept the network if it's unvalidated (1 or 0) 364 * arg2 = whether to remember this choice in the future (1 or 0) 365 * obj = network 366 */ 367 private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28; 368 369 /** 370 * used to specify whether a network should not be penalized when it becomes unvalidated. 371 */ 372 private static final int EVENT_SET_AVOID_UNVALIDATED = 35; 373 374 /** 375 * used to ask the user to confirm a connection to an unvalidated network. 376 * obj = network 377 */ 378 private static final int EVENT_PROMPT_UNVALIDATED = 29; 379 380 /** 381 * used internally to (re)configure mobile data always-on settings. 382 */ 383 private static final int EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON = 30; 384 385 /** 386 * used to add a network listener with a pending intent 387 * obj = NetworkRequestInfo 388 */ 389 private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31; 390 391 /** 392 * Indicates a caller has requested to have its callback invoked with 393 * the latest LinkProperties or NetworkCapabilities. 394 * 395 * arg1 = UID of caller 396 * obj = NetworkRequest 397 */ 398 private static final int EVENT_REQUEST_LINKPROPERTIES = 32; 399 private static final int EVENT_REQUEST_NETCAPABILITIES = 33; 400 401 /** Handler thread used for both of the handlers below. */ 402 @VisibleForTesting 403 protected final HandlerThread mHandlerThread; 404 /** Handler used for internal events. */ 405 final private InternalHandler mHandler; 406 /** Handler used for incoming {@link NetworkStateTracker} events. */ 407 final private NetworkStateTrackerHandler mTrackerHandler; 408 409 private boolean mSystemReady; 410 private Intent mInitialBroadcast; 411 412 private PowerManager.WakeLock mNetTransitionWakeLock; 413 private String mNetTransitionWakeLockCausedBy = ""; 414 private int mNetTransitionWakeLockSerialNumber; 415 private int mNetTransitionWakeLockTimeout; 416 private final PowerManager.WakeLock mPendingIntentWakeLock; 417 418 // used in DBG mode to track inet condition reports 419 private static final int INET_CONDITION_LOG_MAX_SIZE = 15; 420 private ArrayList mInetLog; 421 422 // track the current default http proxy - tell the world if we get a new one (real change) 423 private volatile ProxyInfo mDefaultProxy = null; 424 private Object mProxyLock = new Object(); 425 private boolean mDefaultProxyDisabled = false; 426 427 // track the global proxy. 428 private ProxyInfo mGlobalProxy = null; 429 430 private PacManager mPacManager = null; 431 432 final private SettingsObserver mSettingsObserver; 433 434 private UserManager mUserManager; 435 436 NetworkConfig[] mNetConfigs; 437 int mNetworksDefined; 438 439 // the set of network types that can only be enabled by system/sig apps 440 List mProtectedNetworks; 441 442 private DataConnectionStats mDataConnectionStats; 443 444 TelephonyManager mTelephonyManager; 445 446 private KeepaliveTracker mKeepaliveTracker; 447 private NetworkNotificationManager mNotifier; 448 private LingerMonitor mLingerMonitor; 449 450 // sequence number for Networks; keep in sync with system/netd/NetworkController.cpp 451 private final static int MIN_NET_ID = 100; // some reserved marks 452 private final static int MAX_NET_ID = 65535; 453 private int mNextNetId = MIN_NET_ID; 454 455 // sequence number of NetworkRequests 456 private int mNextNetworkRequestId = 1; 457 458 // NetworkRequest activity String log entries. 459 private static final int MAX_NETWORK_REQUEST_LOGS = 20; 460 private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS); 461 462 // NetworkInfo blocked and unblocked String log entries 463 // TODO: consider reducing memory usage. Each log line is ~40 2B chars, for a total of ~8kB. 464 private static final int MAX_NETWORK_INFO_LOGS = 100; 465 private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS); 466 467 // Array of <Network,ReadOnlyLocalLogs> tracking network validation and results 468 private static final int MAX_VALIDATION_LOGS = 10; 469 private static class ValidationLog { 470 final Network mNetwork; 471 final String mNetworkExtraInfo; 472 final ReadOnlyLocalLog mLog; 473 ValidationLog(Network network, String networkExtraInfo, ReadOnlyLocalLog log)474 ValidationLog(Network network, String networkExtraInfo, ReadOnlyLocalLog log) { 475 mNetwork = network; 476 mNetworkExtraInfo = networkExtraInfo; 477 mLog = log; 478 } 479 } 480 private final ArrayDeque<ValidationLog> mValidationLogs = 481 new ArrayDeque<ValidationLog>(MAX_VALIDATION_LOGS); 482 addValidationLogs(ReadOnlyLocalLog log, Network network, String networkExtraInfo)483 private void addValidationLogs(ReadOnlyLocalLog log, Network network, String networkExtraInfo) { 484 synchronized(mValidationLogs) { 485 while (mValidationLogs.size() >= MAX_VALIDATION_LOGS) { 486 mValidationLogs.removeLast(); 487 } 488 mValidationLogs.addFirst(new ValidationLog(network, networkExtraInfo, log)); 489 } 490 } 491 492 private final IpConnectivityLog mMetricsLog; 493 494 @VisibleForTesting 495 final AvoidBadWifiTracker mAvoidBadWifiTracker; 496 497 /** 498 * Implements support for the legacy "one network per network type" model. 499 * 500 * We used to have a static array of NetworkStateTrackers, one for each 501 * network type, but that doesn't work any more now that we can have, 502 * for example, more that one wifi network. This class stores all the 503 * NetworkAgentInfo objects that support a given type, but the legacy 504 * API will only see the first one. 505 * 506 * It serves two main purposes: 507 * 508 * 1. Provide information about "the network for a given type" (since this 509 * API only supports one). 510 * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if 511 * the first network for a given type changes, or if the default network 512 * changes. 513 */ 514 private class LegacyTypeTracker { 515 516 private static final boolean DBG = true; 517 private static final boolean VDBG = false; 518 519 /** 520 * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS). 521 * Each list holds references to all NetworkAgentInfos that are used to 522 * satisfy requests for that network type. 523 * 524 * This array is built out at startup such that an unsupported network 525 * doesn't get an ArrayList instance, making this a tristate: 526 * unsupported, supported but not active and active. 527 * 528 * The actual lists are populated when we scan the network types that 529 * are supported on this device. 530 * 531 * Threading model: 532 * - addSupportedType() is only called in the constructor 533 * - add(), update(), remove() are only called from the ConnectivityService handler thread. 534 * They are therefore not thread-safe with respect to each other. 535 * - getNetworkForType() can be called at any time on binder threads. It is synchronized 536 * on mTypeLists to be thread-safe with respect to a concurrent remove call. 537 * - dump is thread-safe with respect to concurrent add and remove calls. 538 */ 539 private final ArrayList<NetworkAgentInfo> mTypeLists[]; 540 LegacyTypeTracker()541 public LegacyTypeTracker() { 542 mTypeLists = (ArrayList<NetworkAgentInfo>[]) 543 new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1]; 544 } 545 addSupportedType(int type)546 public void addSupportedType(int type) { 547 if (mTypeLists[type] != null) { 548 throw new IllegalStateException( 549 "legacy list for type " + type + "already initialized"); 550 } 551 mTypeLists[type] = new ArrayList<NetworkAgentInfo>(); 552 } 553 isTypeSupported(int type)554 public boolean isTypeSupported(int type) { 555 return isNetworkTypeValid(type) && mTypeLists[type] != null; 556 } 557 getNetworkForType(int type)558 public NetworkAgentInfo getNetworkForType(int type) { 559 synchronized (mTypeLists) { 560 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) { 561 return mTypeLists[type].get(0); 562 } 563 } 564 return null; 565 } 566 maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork)567 private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, 568 boolean isDefaultNetwork) { 569 if (DBG) { 570 log("Sending " + state + 571 " broadcast for type " + type + " " + nai.name() + 572 " isDefaultNetwork=" + isDefaultNetwork); 573 } 574 } 575 576 /** Adds the given network to the specified legacy type list. */ add(int type, NetworkAgentInfo nai)577 public void add(int type, NetworkAgentInfo nai) { 578 if (!isTypeSupported(type)) { 579 return; // Invalid network type. 580 } 581 if (VDBG) log("Adding agent " + nai + " for legacy network type " + type); 582 583 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 584 if (list.contains(nai)) { 585 return; 586 } 587 synchronized (mTypeLists) { 588 list.add(nai); 589 } 590 591 // Send a broadcast if this is the first network of its type or if it's the default. 592 final boolean isDefaultNetwork = isDefaultNetwork(nai); 593 if ((list.size() == 1) || isDefaultNetwork) { 594 maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork); 595 sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type); 596 } 597 } 598 599 /** Removes the given network from the specified legacy type list. */ remove(int type, NetworkAgentInfo nai, boolean wasDefault)600 public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) { 601 ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 602 if (list == null || list.isEmpty()) { 603 return; 604 } 605 final boolean wasFirstNetwork = list.get(0).equals(nai); 606 607 synchronized (mTypeLists) { 608 if (!list.remove(nai)) { 609 return; 610 } 611 } 612 613 final DetailedState state = DetailedState.DISCONNECTED; 614 615 if (wasFirstNetwork || wasDefault) { 616 maybeLogBroadcast(nai, state, type, wasDefault); 617 sendLegacyNetworkBroadcast(nai, state, type); 618 } 619 620 if (!list.isEmpty() && wasFirstNetwork) { 621 if (DBG) log("Other network available for type " + type + 622 ", sending connected broadcast"); 623 final NetworkAgentInfo replacement = list.get(0); 624 maybeLogBroadcast(replacement, state, type, isDefaultNetwork(replacement)); 625 sendLegacyNetworkBroadcast(replacement, state, type); 626 } 627 } 628 629 /** Removes the given network from all legacy type lists. */ remove(NetworkAgentInfo nai, boolean wasDefault)630 public void remove(NetworkAgentInfo nai, boolean wasDefault) { 631 if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault); 632 for (int type = 0; type < mTypeLists.length; type++) { 633 remove(type, nai, wasDefault); 634 } 635 } 636 637 // send out another legacy broadcast - currently only used for suspend/unsuspend 638 // toggle update(NetworkAgentInfo nai)639 public void update(NetworkAgentInfo nai) { 640 final boolean isDefault = isDefaultNetwork(nai); 641 final DetailedState state = nai.networkInfo.getDetailedState(); 642 for (int type = 0; type < mTypeLists.length; type++) { 643 final ArrayList<NetworkAgentInfo> list = mTypeLists[type]; 644 final boolean contains = (list != null && list.contains(nai)); 645 final boolean isFirst = contains && (nai == list.get(0)); 646 if (isFirst || contains && isDefault) { 647 maybeLogBroadcast(nai, state, type, isDefault); 648 sendLegacyNetworkBroadcast(nai, state, type); 649 } 650 } 651 } 652 naiToString(NetworkAgentInfo nai)653 private String naiToString(NetworkAgentInfo nai) { 654 String name = (nai != null) ? nai.name() : "null"; 655 String state = (nai.networkInfo != null) ? 656 nai.networkInfo.getState() + "/" + nai.networkInfo.getDetailedState() : 657 "???/???"; 658 return name + " " + state; 659 } 660 dump(IndentingPrintWriter pw)661 public void dump(IndentingPrintWriter pw) { 662 pw.println("mLegacyTypeTracker:"); 663 pw.increaseIndent(); 664 pw.print("Supported types:"); 665 for (int type = 0; type < mTypeLists.length; type++) { 666 if (mTypeLists[type] != null) pw.print(" " + type); 667 } 668 pw.println(); 669 pw.println("Current state:"); 670 pw.increaseIndent(); 671 synchronized (mTypeLists) { 672 for (int type = 0; type < mTypeLists.length; type++) { 673 if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue; 674 for (NetworkAgentInfo nai : mTypeLists[type]) { 675 pw.println(type + " " + naiToString(nai)); 676 } 677 } 678 } 679 pw.decreaseIndent(); 680 pw.decreaseIndent(); 681 pw.println(); 682 } 683 } 684 private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(); 685 686 @VisibleForTesting createHandlerThread()687 protected HandlerThread createHandlerThread() { 688 return new HandlerThread("ConnectivityServiceThread"); 689 } 690 ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager)691 public ConnectivityService(Context context, INetworkManagementService netManager, 692 INetworkStatsService statsService, INetworkPolicyManager policyManager) { 693 this(context, netManager, statsService, policyManager, new IpConnectivityLog()); 694 } 695 696 @VisibleForTesting ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager, IpConnectivityLog logger)697 protected ConnectivityService(Context context, INetworkManagementService netManager, 698 INetworkStatsService statsService, INetworkPolicyManager policyManager, 699 IpConnectivityLog logger) { 700 if (DBG) log("ConnectivityService starting up"); 701 702 mMetricsLog = logger; 703 mDefaultRequest = createInternetRequestForTransport(-1); 704 NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder()); 705 mNetworkRequests.put(mDefaultRequest, defaultNRI); 706 mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI); 707 708 mDefaultMobileDataRequest = createInternetRequestForTransport( 709 NetworkCapabilities.TRANSPORT_CELLULAR); 710 711 mHandlerThread = createHandlerThread(); 712 mHandlerThread.start(); 713 mHandler = new InternalHandler(mHandlerThread.getLooper()); 714 mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); 715 716 // setup our unique device name 717 if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) { 718 String id = Settings.Secure.getString(context.getContentResolver(), 719 Settings.Secure.ANDROID_ID); 720 if (id != null && id.length() > 0) { 721 String name = new String("android-").concat(id); 722 SystemProperties.set("net.hostname", name); 723 } 724 } 725 726 mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(), 727 Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000); 728 729 mLingerDelayMs = SystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); 730 731 mContext = checkNotNull(context, "missing Context"); 732 mNetd = checkNotNull(netManager, "missing INetworkManagementService"); 733 mStatsService = checkNotNull(statsService, "missing INetworkStatsService"); 734 mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager"); 735 mKeyStore = KeyStore.getInstance(); 736 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 737 738 try { 739 mPolicyManager.setConnectivityListener(mPolicyListener); 740 mRestrictBackground = mPolicyManager.getRestrictBackground(); 741 } catch (RemoteException e) { 742 // ouch, no rules updates means some processes may never get network 743 loge("unable to register INetworkPolicyListener" + e); 744 } 745 746 final PowerManager powerManager = (PowerManager) context.getSystemService( 747 Context.POWER_SERVICE); 748 mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 749 mNetTransitionWakeLockTimeout = mContext.getResources().getInteger( 750 com.android.internal.R.integer.config_networkTransitionTimeout); 751 mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 752 753 mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1]; 754 755 // TODO: What is the "correct" way to do determine if this is a wifi only device? 756 boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false); 757 log("wifiOnly=" + wifiOnly); 758 String[] naStrings = context.getResources().getStringArray( 759 com.android.internal.R.array.networkAttributes); 760 for (String naString : naStrings) { 761 try { 762 NetworkConfig n = new NetworkConfig(naString); 763 if (VDBG) log("naString=" + naString + " config=" + n); 764 if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) { 765 loge("Error in networkAttributes - ignoring attempt to define type " + 766 n.type); 767 continue; 768 } 769 if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) { 770 log("networkAttributes - ignoring mobile as this dev is wifiOnly " + 771 n.type); 772 continue; 773 } 774 if (mNetConfigs[n.type] != null) { 775 loge("Error in networkAttributes - ignoring attempt to redefine type " + 776 n.type); 777 continue; 778 } 779 mLegacyTypeTracker.addSupportedType(n.type); 780 781 mNetConfigs[n.type] = n; 782 mNetworksDefined++; 783 } catch(Exception e) { 784 // ignore it - leave the entry null 785 } 786 } 787 788 // Forcibly add TYPE_VPN as a supported type, if it has not already been added via config. 789 if (mNetConfigs[TYPE_VPN] == null) { 790 // mNetConfigs is used only for "restore time", which isn't applicable to VPNs, so we 791 // don't need to add TYPE_VPN to mNetConfigs. 792 mLegacyTypeTracker.addSupportedType(TYPE_VPN); 793 mNetworksDefined++; // used only in the log() statement below. 794 } 795 796 if (VDBG) log("mNetworksDefined=" + mNetworksDefined); 797 798 mProtectedNetworks = new ArrayList<Integer>(); 799 int[] protectedNetworks = context.getResources().getIntArray( 800 com.android.internal.R.array.config_protectedNetworks); 801 for (int p : protectedNetworks) { 802 if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) { 803 mProtectedNetworks.add(p); 804 } else { 805 if (DBG) loge("Ignoring protectedNetwork " + p); 806 } 807 } 808 809 mTestMode = SystemProperties.get("cm.test.mode").equals("true") 810 && SystemProperties.get("ro.build.type").equals("eng"); 811 812 mTethering = new Tethering(mContext, mNetd, statsService); 813 814 mPermissionMonitor = new PermissionMonitor(mContext, mNetd); 815 816 //set up the listener for user state for creating user VPNs 817 IntentFilter intentFilter = new IntentFilter(); 818 intentFilter.addAction(Intent.ACTION_USER_STARTED); 819 intentFilter.addAction(Intent.ACTION_USER_STOPPED); 820 intentFilter.addAction(Intent.ACTION_USER_ADDED); 821 intentFilter.addAction(Intent.ACTION_USER_REMOVED); 822 intentFilter.addAction(Intent.ACTION_USER_UNLOCKED); 823 mContext.registerReceiverAsUser( 824 mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null); 825 826 try { 827 mNetd.registerObserver(mTethering); 828 mNetd.registerObserver(mDataActivityObserver); 829 } catch (RemoteException e) { 830 loge("Error registering observer :" + e); 831 } 832 833 if (DBG) { 834 mInetLog = new ArrayList(); 835 } 836 837 mSettingsObserver = new SettingsObserver(mContext, mHandler); 838 registerSettingsCallbacks(); 839 840 mDataConnectionStats = new DataConnectionStats(mContext); 841 mDataConnectionStats.startMonitoring(); 842 843 mPacManager = new PacManager(mContext, mHandler, EVENT_PROXY_HAS_CHANGED); 844 845 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 846 847 mKeepaliveTracker = new KeepaliveTracker(mHandler); 848 mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager, 849 mContext.getSystemService(NotificationManager.class)); 850 851 final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(), 852 Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, 853 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT); 854 final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(), 855 Settings.Global.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS, 856 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS); 857 mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit); 858 859 mAvoidBadWifiTracker = createAvoidBadWifiTracker( 860 mContext, mHandler, () -> rematchForAvoidBadWifiUpdate()); 861 } 862 createInternetRequestForTransport(int transportType)863 private NetworkRequest createInternetRequestForTransport(int transportType) { 864 NetworkCapabilities netCap = new NetworkCapabilities(); 865 netCap.addCapability(NET_CAPABILITY_INTERNET); 866 netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED); 867 if (transportType > -1) { 868 netCap.addTransportType(transportType); 869 } 870 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), 871 NetworkRequest.Type.REQUEST); 872 } 873 874 // Used only for testing. 875 // TODO: Delete this and either: 876 // 1. Give Fake SettingsProvider the ability to send settings change notifications (requires 877 // changing ContentResolver to make registerContentObserver non-final). 878 // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it 879 // by subclassing SettingsObserver. 880 @VisibleForTesting updateMobileDataAlwaysOn()881 void updateMobileDataAlwaysOn() { 882 mHandler.sendEmptyMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON); 883 } 884 handleMobileDataAlwaysOn()885 private void handleMobileDataAlwaysOn() { 886 final boolean enable = (Settings.Global.getInt( 887 mContext.getContentResolver(), Settings.Global.MOBILE_DATA_ALWAYS_ON, 0) == 1); 888 final boolean isEnabled = (mNetworkRequests.get(mDefaultMobileDataRequest) != null); 889 if (enable == isEnabled) { 890 return; // Nothing to do. 891 } 892 893 if (enable) { 894 handleRegisterNetworkRequest(new NetworkRequestInfo( 895 null, mDefaultMobileDataRequest, new Binder())); 896 } else { 897 handleReleaseNetworkRequest(mDefaultMobileDataRequest, Process.SYSTEM_UID); 898 } 899 } 900 registerSettingsCallbacks()901 private void registerSettingsCallbacks() { 902 // Watch for global HTTP proxy changes. 903 mSettingsObserver.observe( 904 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY), 905 EVENT_APPLY_GLOBAL_HTTP_PROXY); 906 907 // Watch for whether or not to keep mobile data always on. 908 mSettingsObserver.observe( 909 Settings.Global.getUriFor(Settings.Global.MOBILE_DATA_ALWAYS_ON), 910 EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON); 911 } 912 nextNetworkRequestId()913 private synchronized int nextNetworkRequestId() { 914 return mNextNetworkRequestId++; 915 } 916 917 @VisibleForTesting reserveNetId()918 protected int reserveNetId() { 919 synchronized (mNetworkForNetId) { 920 for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) { 921 int netId = mNextNetId; 922 if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID; 923 // Make sure NetID unused. http://b/16815182 924 if (!mNetIdInUse.get(netId)) { 925 mNetIdInUse.put(netId, true); 926 return netId; 927 } 928 } 929 } 930 throw new IllegalStateException("No free netIds"); 931 } 932 getFilteredNetworkState(int networkType, int uid, boolean ignoreBlocked)933 private NetworkState getFilteredNetworkState(int networkType, int uid, boolean ignoreBlocked) { 934 if (mLegacyTypeTracker.isTypeSupported(networkType)) { 935 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 936 final NetworkState state; 937 if (nai != null) { 938 state = nai.getNetworkState(); 939 state.networkInfo.setType(networkType); 940 } else { 941 final NetworkInfo info = new NetworkInfo(networkType, 0, 942 getNetworkTypeName(networkType), ""); 943 info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null); 944 info.setIsAvailable(true); 945 state = new NetworkState(info, new LinkProperties(), new NetworkCapabilities(), 946 null, null, null); 947 } 948 filterNetworkStateForUid(state, uid, ignoreBlocked); 949 return state; 950 } else { 951 return NetworkState.EMPTY; 952 } 953 } 954 getNetworkAgentInfoForNetwork(Network network)955 private NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) { 956 if (network == null) { 957 return null; 958 } 959 synchronized (mNetworkForNetId) { 960 return mNetworkForNetId.get(network.netId); 961 } 962 } 963 getVpnUnderlyingNetworks(int uid)964 private Network[] getVpnUnderlyingNetworks(int uid) { 965 if (!mLockdownEnabled) { 966 int user = UserHandle.getUserId(uid); 967 synchronized (mVpns) { 968 Vpn vpn = mVpns.get(user); 969 if (vpn != null && vpn.appliesToUid(uid)) { 970 return vpn.getUnderlyingNetworks(); 971 } 972 } 973 } 974 return null; 975 } 976 getUnfilteredActiveNetworkState(int uid)977 private NetworkState getUnfilteredActiveNetworkState(int uid) { 978 NetworkAgentInfo nai = getDefaultNetwork(); 979 980 final Network[] networks = getVpnUnderlyingNetworks(uid); 981 if (networks != null) { 982 // getUnderlyingNetworks() returns: 983 // null => there was no VPN, or the VPN didn't specify anything, so we use the default. 984 // empty array => the VPN explicitly said "no default network". 985 // non-empty array => the VPN specified one or more default networks; we use the 986 // first one. 987 if (networks.length > 0) { 988 nai = getNetworkAgentInfoForNetwork(networks[0]); 989 } else { 990 nai = null; 991 } 992 } 993 994 if (nai != null) { 995 return nai.getNetworkState(); 996 } else { 997 return NetworkState.EMPTY; 998 } 999 } 1000 1001 /** 1002 * Check if UID should be blocked from using the network with the given LinkProperties. 1003 */ isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid, boolean ignoreBlocked)1004 private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid, 1005 boolean ignoreBlocked) { 1006 // Networks aren't blocked when ignoring blocked status 1007 if (ignoreBlocked) return false; 1008 // Networks are never blocked for system services 1009 if (isSystem(uid)) return false; 1010 1011 final boolean networkMetered; 1012 final int uidRules; 1013 1014 synchronized (mVpns) { 1015 final Vpn vpn = mVpns.get(UserHandle.getUserId(uid)); 1016 if (vpn != null && vpn.isBlockingUid(uid)) { 1017 return true; 1018 } 1019 } 1020 1021 final String iface = (lp == null ? "" : lp.getInterfaceName()); 1022 synchronized (mRulesLock) { 1023 networkMetered = mMeteredIfaces.contains(iface); 1024 uidRules = mUidRules.get(uid, RULE_NONE); 1025 } 1026 1027 boolean allowed = true; 1028 // Check Data Saver Mode first... 1029 if (networkMetered) { 1030 if ((uidRules & RULE_REJECT_METERED) != 0) { 1031 if (LOGD_RULES) Log.d(TAG, "uid " + uid + " is blacklisted"); 1032 // Explicitly blacklisted. 1033 allowed = false; 1034 } else { 1035 allowed = !mRestrictBackground 1036 || (uidRules & RULE_ALLOW_METERED) != 0 1037 || (uidRules & RULE_TEMPORARY_ALLOW_METERED) != 0; 1038 if (LOGD_RULES) Log.d(TAG, "allowed status for uid " + uid + " when" 1039 + " mRestrictBackground=" + mRestrictBackground 1040 + ", whitelisted=" + ((uidRules & RULE_ALLOW_METERED) != 0) 1041 + ", tempWhitelist= + ((uidRules & RULE_TEMPORARY_ALLOW_METERED) != 0)" 1042 + ": " + allowed); 1043 } 1044 } 1045 // ...then power restrictions. 1046 if (allowed) { 1047 allowed = (uidRules & RULE_REJECT_ALL) == 0; 1048 if (LOGD_RULES) Log.d(TAG, "allowed status for uid " + uid + " when" 1049 + " rule is " + uidRulesToString(uidRules) + ": " + allowed); 1050 } 1051 return !allowed; 1052 } 1053 maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid)1054 private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) { 1055 if (ni == null || !LOGD_BLOCKED_NETWORKINFO) { 1056 return; 1057 } 1058 boolean removed = false; 1059 boolean added = false; 1060 synchronized (mBlockedAppUids) { 1061 if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) { 1062 added = true; 1063 } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) { 1064 removed = true; 1065 } 1066 } 1067 if (added) { 1068 log("Returning blocked NetworkInfo to uid=" + uid); 1069 mNetworkInfoBlockingLogs.log("BLOCKED " + uid); 1070 } else if (removed) { 1071 log("Returning unblocked NetworkInfo to uid=" + uid); 1072 mNetworkInfoBlockingLogs.log("UNBLOCKED " + uid); 1073 } 1074 } 1075 1076 /** 1077 * Apply any relevant filters to {@link NetworkState} for the given UID. For 1078 * example, this may mark the network as {@link DetailedState#BLOCKED} based 1079 * on {@link #isNetworkWithLinkPropertiesBlocked}, or 1080 * {@link NetworkInfo#isMetered()} based on network policies. 1081 */ filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked)1082 private void filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked) { 1083 if (state == null || state.networkInfo == null || state.linkProperties == null) return; 1084 1085 if (isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, ignoreBlocked)) { 1086 state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null); 1087 } 1088 if (mLockdownTracker != null) { 1089 mLockdownTracker.augmentNetworkInfo(state.networkInfo); 1090 } 1091 1092 // TODO: apply metered state closer to NetworkAgentInfo 1093 final long token = Binder.clearCallingIdentity(); 1094 try { 1095 state.networkInfo.setMetered(mPolicyManager.isNetworkMetered(state)); 1096 } catch (RemoteException e) { 1097 } finally { 1098 Binder.restoreCallingIdentity(token); 1099 } 1100 } 1101 1102 /** 1103 * Return NetworkInfo for the active (i.e., connected) network interface. 1104 * It is assumed that at most one network is active at a time. If more 1105 * than one is active, it is indeterminate which will be returned. 1106 * @return the info for the active network, or {@code null} if none is 1107 * active 1108 */ 1109 @Override getActiveNetworkInfo()1110 public NetworkInfo getActiveNetworkInfo() { 1111 enforceAccessPermission(); 1112 final int uid = Binder.getCallingUid(); 1113 final NetworkState state = getUnfilteredActiveNetworkState(uid); 1114 filterNetworkStateForUid(state, uid, false); 1115 maybeLogBlockedNetworkInfo(state.networkInfo, uid); 1116 return state.networkInfo; 1117 } 1118 1119 @Override getActiveNetwork()1120 public Network getActiveNetwork() { 1121 enforceAccessPermission(); 1122 return getActiveNetworkForUidInternal(Binder.getCallingUid(), false); 1123 } 1124 1125 @Override getActiveNetworkForUid(int uid, boolean ignoreBlocked)1126 public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) { 1127 enforceConnectivityInternalPermission(); 1128 return getActiveNetworkForUidInternal(uid, ignoreBlocked); 1129 } 1130 getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked)1131 private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) { 1132 final int user = UserHandle.getUserId(uid); 1133 int vpnNetId = NETID_UNSET; 1134 synchronized (mVpns) { 1135 final Vpn vpn = mVpns.get(user); 1136 if (vpn != null && vpn.appliesToUid(uid)) vpnNetId = vpn.getNetId(); 1137 } 1138 NetworkAgentInfo nai; 1139 if (vpnNetId != NETID_UNSET) { 1140 synchronized (mNetworkForNetId) { 1141 nai = mNetworkForNetId.get(vpnNetId); 1142 } 1143 if (nai != null) return nai.network; 1144 } 1145 nai = getDefaultNetwork(); 1146 if (nai != null 1147 && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, ignoreBlocked)) { 1148 nai = null; 1149 } 1150 return nai != null ? nai.network : null; 1151 } 1152 1153 // Public because it's used by mLockdownTracker. getActiveNetworkInfoUnfiltered()1154 public NetworkInfo getActiveNetworkInfoUnfiltered() { 1155 enforceAccessPermission(); 1156 final int uid = Binder.getCallingUid(); 1157 NetworkState state = getUnfilteredActiveNetworkState(uid); 1158 return state.networkInfo; 1159 } 1160 1161 @Override getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked)1162 public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) { 1163 enforceConnectivityInternalPermission(); 1164 final NetworkState state = getUnfilteredActiveNetworkState(uid); 1165 filterNetworkStateForUid(state, uid, ignoreBlocked); 1166 return state.networkInfo; 1167 } 1168 1169 @Override getNetworkInfo(int networkType)1170 public NetworkInfo getNetworkInfo(int networkType) { 1171 enforceAccessPermission(); 1172 final int uid = Binder.getCallingUid(); 1173 if (getVpnUnderlyingNetworks(uid) != null) { 1174 // A VPN is active, so we may need to return one of its underlying networks. This 1175 // information is not available in LegacyTypeTracker, so we have to get it from 1176 // getUnfilteredActiveNetworkState. 1177 final NetworkState state = getUnfilteredActiveNetworkState(uid); 1178 if (state.networkInfo != null && state.networkInfo.getType() == networkType) { 1179 filterNetworkStateForUid(state, uid, false); 1180 return state.networkInfo; 1181 } 1182 } 1183 final NetworkState state = getFilteredNetworkState(networkType, uid, false); 1184 return state.networkInfo; 1185 } 1186 1187 @Override getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked)1188 public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) { 1189 enforceAccessPermission(); 1190 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 1191 if (nai != null) { 1192 final NetworkState state = nai.getNetworkState(); 1193 filterNetworkStateForUid(state, uid, ignoreBlocked); 1194 return state.networkInfo; 1195 } else { 1196 return null; 1197 } 1198 } 1199 1200 @Override getAllNetworkInfo()1201 public NetworkInfo[] getAllNetworkInfo() { 1202 enforceAccessPermission(); 1203 final ArrayList<NetworkInfo> result = Lists.newArrayList(); 1204 for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE; 1205 networkType++) { 1206 NetworkInfo info = getNetworkInfo(networkType); 1207 if (info != null) { 1208 result.add(info); 1209 } 1210 } 1211 return result.toArray(new NetworkInfo[result.size()]); 1212 } 1213 1214 @Override getNetworkForType(int networkType)1215 public Network getNetworkForType(int networkType) { 1216 enforceAccessPermission(); 1217 final int uid = Binder.getCallingUid(); 1218 NetworkState state = getFilteredNetworkState(networkType, uid, false); 1219 if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, false)) { 1220 return state.network; 1221 } 1222 return null; 1223 } 1224 1225 @Override getAllNetworks()1226 public Network[] getAllNetworks() { 1227 enforceAccessPermission(); 1228 synchronized (mNetworkForNetId) { 1229 final Network[] result = new Network[mNetworkForNetId.size()]; 1230 for (int i = 0; i < mNetworkForNetId.size(); i++) { 1231 result[i] = mNetworkForNetId.valueAt(i).network; 1232 } 1233 return result; 1234 } 1235 } 1236 1237 @Override getDefaultNetworkCapabilitiesForUser(int userId)1238 public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) { 1239 // The basic principle is: if an app's traffic could possibly go over a 1240 // network, without the app doing anything multinetwork-specific, 1241 // (hence, by "default"), then include that network's capabilities in 1242 // the array. 1243 // 1244 // In the normal case, app traffic only goes over the system's default 1245 // network connection, so that's the only network returned. 1246 // 1247 // With a VPN in force, some app traffic may go into the VPN, and thus 1248 // over whatever underlying networks the VPN specifies, while other app 1249 // traffic may go over the system default network (e.g.: a split-tunnel 1250 // VPN, or an app disallowed by the VPN), so the set of networks 1251 // returned includes the VPN's underlying networks and the system 1252 // default. 1253 enforceAccessPermission(); 1254 1255 HashMap<Network, NetworkCapabilities> result = new HashMap<Network, NetworkCapabilities>(); 1256 1257 NetworkAgentInfo nai = getDefaultNetwork(); 1258 NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai); 1259 if (nc != null) { 1260 result.put(nai.network, nc); 1261 } 1262 1263 if (!mLockdownEnabled) { 1264 synchronized (mVpns) { 1265 Vpn vpn = mVpns.get(userId); 1266 if (vpn != null) { 1267 Network[] networks = vpn.getUnderlyingNetworks(); 1268 if (networks != null) { 1269 for (Network network : networks) { 1270 nai = getNetworkAgentInfoForNetwork(network); 1271 nc = getNetworkCapabilitiesInternal(nai); 1272 if (nc != null) { 1273 result.put(network, nc); 1274 } 1275 } 1276 } 1277 } 1278 } 1279 } 1280 1281 NetworkCapabilities[] out = new NetworkCapabilities[result.size()]; 1282 out = result.values().toArray(out); 1283 return out; 1284 } 1285 1286 @Override isNetworkSupported(int networkType)1287 public boolean isNetworkSupported(int networkType) { 1288 enforceAccessPermission(); 1289 return mLegacyTypeTracker.isTypeSupported(networkType); 1290 } 1291 1292 /** 1293 * Return LinkProperties for the active (i.e., connected) default 1294 * network interface. It is assumed that at most one default network 1295 * is active at a time. If more than one is active, it is indeterminate 1296 * which will be returned. 1297 * @return the ip properties for the active network, or {@code null} if 1298 * none is active 1299 */ 1300 @Override getActiveLinkProperties()1301 public LinkProperties getActiveLinkProperties() { 1302 enforceAccessPermission(); 1303 final int uid = Binder.getCallingUid(); 1304 NetworkState state = getUnfilteredActiveNetworkState(uid); 1305 return state.linkProperties; 1306 } 1307 1308 @Override getLinkPropertiesForType(int networkType)1309 public LinkProperties getLinkPropertiesForType(int networkType) { 1310 enforceAccessPermission(); 1311 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 1312 if (nai != null) { 1313 synchronized (nai) { 1314 return new LinkProperties(nai.linkProperties); 1315 } 1316 } 1317 return null; 1318 } 1319 1320 // TODO - this should be ALL networks 1321 @Override getLinkProperties(Network network)1322 public LinkProperties getLinkProperties(Network network) { 1323 enforceAccessPermission(); 1324 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 1325 if (nai != null) { 1326 synchronized (nai) { 1327 return new LinkProperties(nai.linkProperties); 1328 } 1329 } 1330 return null; 1331 } 1332 getNetworkCapabilitiesInternal(NetworkAgentInfo nai)1333 private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) { 1334 if (nai != null) { 1335 synchronized (nai) { 1336 if (nai.networkCapabilities != null) { 1337 return new NetworkCapabilities(nai.networkCapabilities); 1338 } 1339 } 1340 } 1341 return null; 1342 } 1343 1344 @Override getNetworkCapabilities(Network network)1345 public NetworkCapabilities getNetworkCapabilities(Network network) { 1346 enforceAccessPermission(); 1347 return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network)); 1348 } 1349 1350 @Override getAllNetworkState()1351 public NetworkState[] getAllNetworkState() { 1352 // Require internal since we're handing out IMSI details 1353 enforceConnectivityInternalPermission(); 1354 1355 final ArrayList<NetworkState> result = Lists.newArrayList(); 1356 for (Network network : getAllNetworks()) { 1357 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 1358 if (nai != null) { 1359 result.add(nai.getNetworkState()); 1360 } 1361 } 1362 return result.toArray(new NetworkState[result.size()]); 1363 } 1364 1365 @Override getActiveNetworkQuotaInfo()1366 public NetworkQuotaInfo getActiveNetworkQuotaInfo() { 1367 enforceAccessPermission(); 1368 final int uid = Binder.getCallingUid(); 1369 final long token = Binder.clearCallingIdentity(); 1370 try { 1371 final NetworkState state = getUnfilteredActiveNetworkState(uid); 1372 if (state.networkInfo != null) { 1373 try { 1374 return mPolicyManager.getNetworkQuotaInfo(state); 1375 } catch (RemoteException e) { 1376 } 1377 } 1378 return null; 1379 } finally { 1380 Binder.restoreCallingIdentity(token); 1381 } 1382 } 1383 1384 @Override isActiveNetworkMetered()1385 public boolean isActiveNetworkMetered() { 1386 enforceAccessPermission(); 1387 1388 final NetworkInfo info = getActiveNetworkInfo(); 1389 return (info != null) ? info.isMetered() : false; 1390 } 1391 1392 private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() { 1393 @Override 1394 public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) { 1395 int deviceType = Integer.parseInt(label); 1396 sendDataActivityBroadcast(deviceType, active, tsNanos); 1397 } 1398 }; 1399 1400 /** 1401 * Ensure that a network route exists to deliver traffic to the specified 1402 * host via the specified network interface. 1403 * @param networkType the type of the network over which traffic to the 1404 * specified host is to be routed 1405 * @param hostAddress the IP address of the host to which the route is 1406 * desired 1407 * @return {@code true} on success, {@code false} on failure 1408 */ 1409 @Override requestRouteToHostAddress(int networkType, byte[] hostAddress)1410 public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) { 1411 enforceChangePermission(); 1412 if (mProtectedNetworks.contains(networkType)) { 1413 enforceConnectivityInternalPermission(); 1414 } 1415 1416 InetAddress addr; 1417 try { 1418 addr = InetAddress.getByAddress(hostAddress); 1419 } catch (UnknownHostException e) { 1420 if (DBG) log("requestRouteToHostAddress got " + e.toString()); 1421 return false; 1422 } 1423 1424 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 1425 if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType); 1426 return false; 1427 } 1428 1429 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 1430 if (nai == null) { 1431 if (mLegacyTypeTracker.isTypeSupported(networkType) == false) { 1432 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType); 1433 } else { 1434 if (DBG) log("requestRouteToHostAddress on down network: " + networkType); 1435 } 1436 return false; 1437 } 1438 1439 DetailedState netState; 1440 synchronized (nai) { 1441 netState = nai.networkInfo.getDetailedState(); 1442 } 1443 1444 if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) { 1445 if (VDBG) { 1446 log("requestRouteToHostAddress on down network " 1447 + "(" + networkType + ") - dropped" 1448 + " netState=" + netState); 1449 } 1450 return false; 1451 } 1452 1453 final int uid = Binder.getCallingUid(); 1454 final long token = Binder.clearCallingIdentity(); 1455 try { 1456 LinkProperties lp; 1457 int netId; 1458 synchronized (nai) { 1459 lp = nai.linkProperties; 1460 netId = nai.network.netId; 1461 } 1462 boolean ok = addLegacyRouteToHost(lp, addr, netId, uid); 1463 if (DBG) log("requestRouteToHostAddress ok=" + ok); 1464 return ok; 1465 } finally { 1466 Binder.restoreCallingIdentity(token); 1467 } 1468 } 1469 addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid)1470 private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) { 1471 RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr); 1472 if (bestRoute == null) { 1473 bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName()); 1474 } else { 1475 String iface = bestRoute.getInterface(); 1476 if (bestRoute.getGateway().equals(addr)) { 1477 // if there is no better route, add the implied hostroute for our gateway 1478 bestRoute = RouteInfo.makeHostRoute(addr, iface); 1479 } else { 1480 // if we will connect to this through another route, add a direct route 1481 // to it's gateway 1482 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface); 1483 } 1484 } 1485 if (DBG) log("Adding legacy route " + bestRoute + 1486 " for UID/PID " + uid + "/" + Binder.getCallingPid()); 1487 try { 1488 mNetd.addLegacyRouteForNetId(netId, bestRoute, uid); 1489 } catch (Exception e) { 1490 // never crash - catch them all 1491 if (DBG) loge("Exception trying to add a route: " + e); 1492 return false; 1493 } 1494 return true; 1495 } 1496 1497 private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() { 1498 @Override 1499 public void onUidRulesChanged(int uid, int uidRules) { 1500 // caller is NPMS, since we only register with them 1501 if (LOGD_RULES) { 1502 log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")"); 1503 } 1504 1505 synchronized (mRulesLock) { 1506 // skip update when we've already applied rules 1507 final int oldRules = mUidRules.get(uid, RULE_NONE); 1508 if (oldRules == uidRules) return; 1509 1510 if (uidRules == RULE_NONE) { 1511 mUidRules.delete(uid); 1512 } else { 1513 mUidRules.put(uid, uidRules); 1514 } 1515 } 1516 1517 // TODO: notify UID when it has requested targeted updates 1518 } 1519 1520 @Override 1521 public void onMeteredIfacesChanged(String[] meteredIfaces) { 1522 // caller is NPMS, since we only register with them 1523 if (LOGD_RULES) { 1524 log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")"); 1525 } 1526 1527 synchronized (mRulesLock) { 1528 mMeteredIfaces.clear(); 1529 for (String iface : meteredIfaces) { 1530 mMeteredIfaces.add(iface); 1531 } 1532 } 1533 } 1534 1535 @Override 1536 public void onRestrictBackgroundChanged(boolean restrictBackground) { 1537 // caller is NPMS, since we only register with them 1538 if (LOGD_RULES) { 1539 log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")"); 1540 } 1541 1542 synchronized (mRulesLock) { 1543 mRestrictBackground = restrictBackground; 1544 } 1545 1546 if (restrictBackground) { 1547 log("onRestrictBackgroundChanged(true): disabling tethering"); 1548 mTethering.untetherAll(); 1549 } 1550 } 1551 1552 @Override 1553 public void onRestrictBackgroundWhitelistChanged(int uid, boolean whitelisted) { 1554 if (LOGD_RULES) { 1555 // caller is NPMS, since we only register with them 1556 log("onRestrictBackgroundWhitelistChanged(uid=" + uid + ", whitelisted=" 1557 + whitelisted + ")"); 1558 } 1559 } 1560 @Override 1561 public void onRestrictBackgroundBlacklistChanged(int uid, boolean blacklisted) { 1562 if (LOGD_RULES) { 1563 // caller is NPMS, since we only register with them 1564 log("onRestrictBackgroundBlacklistChanged(uid=" + uid + ", blacklisted=" 1565 + blacklisted + ")"); 1566 } 1567 } 1568 }; 1569 1570 /** 1571 * Require that the caller is either in the same user or has appropriate permission to interact 1572 * across users. 1573 * 1574 * @param userId Target user for whatever operation the current IPC is supposed to perform. 1575 */ enforceCrossUserPermission(int userId)1576 private void enforceCrossUserPermission(int userId) { 1577 if (userId == UserHandle.getCallingUserId()) { 1578 // Not a cross-user call. 1579 return; 1580 } 1581 mContext.enforceCallingOrSelfPermission( 1582 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 1583 "ConnectivityService"); 1584 } 1585 enforceInternetPermission()1586 private void enforceInternetPermission() { 1587 mContext.enforceCallingOrSelfPermission( 1588 android.Manifest.permission.INTERNET, 1589 "ConnectivityService"); 1590 } 1591 enforceAccessPermission()1592 private void enforceAccessPermission() { 1593 mContext.enforceCallingOrSelfPermission( 1594 android.Manifest.permission.ACCESS_NETWORK_STATE, 1595 "ConnectivityService"); 1596 } 1597 enforceChangePermission()1598 private void enforceChangePermission() { 1599 ConnectivityManager.enforceChangePermission(mContext); 1600 } 1601 enforceTetherAccessPermission()1602 private void enforceTetherAccessPermission() { 1603 mContext.enforceCallingOrSelfPermission( 1604 android.Manifest.permission.ACCESS_NETWORK_STATE, 1605 "ConnectivityService"); 1606 } 1607 enforceConnectivityInternalPermission()1608 private void enforceConnectivityInternalPermission() { 1609 mContext.enforceCallingOrSelfPermission( 1610 android.Manifest.permission.CONNECTIVITY_INTERNAL, 1611 "ConnectivityService"); 1612 } 1613 enforceConnectivityRestrictedNetworksPermission()1614 private void enforceConnectivityRestrictedNetworksPermission() { 1615 try { 1616 mContext.enforceCallingOrSelfPermission( 1617 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS, 1618 "ConnectivityService"); 1619 return; 1620 } catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ } 1621 enforceConnectivityInternalPermission(); 1622 } 1623 enforceKeepalivePermission()1624 private void enforceKeepalivePermission() { 1625 mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService"); 1626 } 1627 1628 // Public because it's used by mLockdownTracker. sendConnectedBroadcast(NetworkInfo info)1629 public void sendConnectedBroadcast(NetworkInfo info) { 1630 enforceConnectivityInternalPermission(); 1631 sendGeneralBroadcast(info, CONNECTIVITY_ACTION); 1632 } 1633 sendInetConditionBroadcast(NetworkInfo info)1634 private void sendInetConditionBroadcast(NetworkInfo info) { 1635 sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION); 1636 } 1637 makeGeneralIntent(NetworkInfo info, String bcastType)1638 private Intent makeGeneralIntent(NetworkInfo info, String bcastType) { 1639 if (mLockdownTracker != null) { 1640 info = new NetworkInfo(info); 1641 mLockdownTracker.augmentNetworkInfo(info); 1642 } 1643 1644 Intent intent = new Intent(bcastType); 1645 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info)); 1646 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 1647 if (info.isFailover()) { 1648 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 1649 info.setFailover(false); 1650 } 1651 if (info.getReason() != null) { 1652 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 1653 } 1654 if (info.getExtraInfo() != null) { 1655 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, 1656 info.getExtraInfo()); 1657 } 1658 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); 1659 return intent; 1660 } 1661 sendGeneralBroadcast(NetworkInfo info, String bcastType)1662 private void sendGeneralBroadcast(NetworkInfo info, String bcastType) { 1663 sendStickyBroadcast(makeGeneralIntent(info, bcastType)); 1664 } 1665 sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos)1666 private void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) { 1667 Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE); 1668 intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType); 1669 intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active); 1670 intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos); 1671 final long ident = Binder.clearCallingIdentity(); 1672 try { 1673 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL, 1674 RECEIVE_DATA_ACTIVITY_CHANGE, null, null, 0, null, null); 1675 } finally { 1676 Binder.restoreCallingIdentity(ident); 1677 } 1678 } 1679 sendStickyBroadcast(Intent intent)1680 private void sendStickyBroadcast(Intent intent) { 1681 synchronized(this) { 1682 if (!mSystemReady) { 1683 mInitialBroadcast = new Intent(intent); 1684 } 1685 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1686 if (VDBG) { 1687 log("sendStickyBroadcast: action=" + intent.getAction()); 1688 } 1689 1690 Bundle options = null; 1691 final long ident = Binder.clearCallingIdentity(); 1692 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 1693 final NetworkInfo ni = intent.getParcelableExtra( 1694 ConnectivityManager.EXTRA_NETWORK_INFO); 1695 if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) { 1696 intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL); 1697 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 1698 } else { 1699 BroadcastOptions opts = BroadcastOptions.makeBasic(); 1700 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); 1701 options = opts.toBundle(); 1702 } 1703 final IBatteryStats bs = BatteryStatsService.getService(); 1704 try { 1705 bs.noteConnectivityChanged(intent.getIntExtra( 1706 ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_NONE), 1707 ni != null ? ni.getState().toString() : "?"); 1708 } catch (RemoteException e) { 1709 } 1710 } 1711 try { 1712 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL, options); 1713 } finally { 1714 Binder.restoreCallingIdentity(ident); 1715 } 1716 } 1717 } 1718 systemReady()1719 void systemReady() { 1720 loadGlobalProxy(); 1721 1722 synchronized(this) { 1723 mSystemReady = true; 1724 if (mInitialBroadcast != null) { 1725 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL); 1726 mInitialBroadcast = null; 1727 } 1728 } 1729 // load the global proxy at startup 1730 mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY)); 1731 1732 // Try bringing up tracker, but KeyStore won't be ready yet for secondary users so wait 1733 // for user to unlock device too. 1734 updateLockdownVpn(); 1735 1736 // Configure whether mobile data is always on. 1737 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON)); 1738 1739 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY)); 1740 1741 mPermissionMonitor.startMonitoring(); 1742 } 1743 1744 /** 1745 * Setup data activity tracking for the given network. 1746 * 1747 * Every {@code setupDataActivityTracking} should be paired with a 1748 * {@link #removeDataActivityTracking} for cleanup. 1749 */ setupDataActivityTracking(NetworkAgentInfo networkAgent)1750 private void setupDataActivityTracking(NetworkAgentInfo networkAgent) { 1751 final String iface = networkAgent.linkProperties.getInterfaceName(); 1752 1753 final int timeout; 1754 int type = ConnectivityManager.TYPE_NONE; 1755 1756 if (networkAgent.networkCapabilities.hasTransport( 1757 NetworkCapabilities.TRANSPORT_CELLULAR)) { 1758 timeout = Settings.Global.getInt(mContext.getContentResolver(), 1759 Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE, 1760 10); 1761 type = ConnectivityManager.TYPE_MOBILE; 1762 } else if (networkAgent.networkCapabilities.hasTransport( 1763 NetworkCapabilities.TRANSPORT_WIFI)) { 1764 timeout = Settings.Global.getInt(mContext.getContentResolver(), 1765 Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI, 1766 15); 1767 type = ConnectivityManager.TYPE_WIFI; 1768 } else { 1769 // do not track any other networks 1770 timeout = 0; 1771 } 1772 1773 if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) { 1774 try { 1775 mNetd.addIdleTimer(iface, timeout, type); 1776 } catch (Exception e) { 1777 // You shall not crash! 1778 loge("Exception in setupDataActivityTracking " + e); 1779 } 1780 } 1781 } 1782 1783 /** 1784 * Remove data activity tracking when network disconnects. 1785 */ removeDataActivityTracking(NetworkAgentInfo networkAgent)1786 private void removeDataActivityTracking(NetworkAgentInfo networkAgent) { 1787 final String iface = networkAgent.linkProperties.getInterfaceName(); 1788 final NetworkCapabilities caps = networkAgent.networkCapabilities; 1789 1790 if (iface != null && (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || 1791 caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) { 1792 try { 1793 // the call fails silently if no idletimer setup for this interface 1794 mNetd.removeIdleTimer(iface); 1795 } catch (Exception e) { 1796 loge("Exception in removeDataActivityTracking " + e); 1797 } 1798 } 1799 } 1800 1801 /** 1802 * Reads the network specific MTU size from reources. 1803 * and set it on it's iface. 1804 */ updateMtu(LinkProperties newLp, LinkProperties oldLp)1805 private void updateMtu(LinkProperties newLp, LinkProperties oldLp) { 1806 final String iface = newLp.getInterfaceName(); 1807 final int mtu = newLp.getMtu(); 1808 if (oldLp != null && newLp.isIdenticalMtu(oldLp)) { 1809 if (VDBG) log("identical MTU - not setting"); 1810 return; 1811 } 1812 1813 if (LinkProperties.isValidMtu(mtu, newLp.hasGlobalIPv6Address()) == false) { 1814 if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface); 1815 return; 1816 } 1817 1818 // Cannot set MTU without interface name 1819 if (TextUtils.isEmpty(iface)) { 1820 loge("Setting MTU size with null iface."); 1821 return; 1822 } 1823 1824 try { 1825 if (VDBG) log("Setting MTU size: " + iface + ", " + mtu); 1826 mNetd.setMtu(iface, mtu); 1827 } catch (Exception e) { 1828 Slog.e(TAG, "exception in setMtu()" + e); 1829 } 1830 } 1831 1832 private static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; 1833 private static final String DEFAULT_TCP_RWND_KEY = "net.tcp.default_init_rwnd"; 1834 1835 // Overridden for testing purposes to avoid writing to SystemProperties. 1836 @VisibleForTesting getDefaultTcpRwnd()1837 protected int getDefaultTcpRwnd() { 1838 return SystemProperties.getInt(DEFAULT_TCP_RWND_KEY, 0); 1839 } 1840 updateTcpBufferSizes(NetworkAgentInfo nai)1841 private void updateTcpBufferSizes(NetworkAgentInfo nai) { 1842 if (isDefaultNetwork(nai) == false) { 1843 return; 1844 } 1845 1846 String tcpBufferSizes = nai.linkProperties.getTcpBufferSizes(); 1847 String[] values = null; 1848 if (tcpBufferSizes != null) { 1849 values = tcpBufferSizes.split(","); 1850 } 1851 1852 if (values == null || values.length != 6) { 1853 if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults"); 1854 tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES; 1855 values = tcpBufferSizes.split(","); 1856 } 1857 1858 if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return; 1859 1860 try { 1861 if (VDBG) Slog.d(TAG, "Setting tx/rx TCP buffers to " + tcpBufferSizes); 1862 1863 final String prefix = "/sys/kernel/ipv4/tcp_"; 1864 FileUtils.stringToFile(prefix + "rmem_min", values[0]); 1865 FileUtils.stringToFile(prefix + "rmem_def", values[1]); 1866 FileUtils.stringToFile(prefix + "rmem_max", values[2]); 1867 FileUtils.stringToFile(prefix + "wmem_min", values[3]); 1868 FileUtils.stringToFile(prefix + "wmem_def", values[4]); 1869 FileUtils.stringToFile(prefix + "wmem_max", values[5]); 1870 mCurrentTcpBufferSizes = tcpBufferSizes; 1871 } catch (IOException e) { 1872 loge("Can't set TCP buffer sizes:" + e); 1873 } 1874 1875 Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(), 1876 Settings.Global.TCP_DEFAULT_INIT_RWND, getDefaultTcpRwnd()); 1877 final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd"; 1878 if (rwndValue != 0) { 1879 SystemProperties.set(sysctlKey, rwndValue.toString()); 1880 } 1881 } 1882 flushVmDnsCache()1883 private void flushVmDnsCache() { 1884 /* 1885 * Tell the VMs to toss their DNS caches 1886 */ 1887 Intent intent = new Intent(Intent.ACTION_CLEAR_DNS_CACHE); 1888 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1889 /* 1890 * Connectivity events can happen before boot has completed ... 1891 */ 1892 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1893 final long ident = Binder.clearCallingIdentity(); 1894 try { 1895 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 1896 } finally { 1897 Binder.restoreCallingIdentity(ident); 1898 } 1899 } 1900 1901 @Override getRestoreDefaultNetworkDelay(int networkType)1902 public int getRestoreDefaultNetworkDelay(int networkType) { 1903 String restoreDefaultNetworkDelayStr = SystemProperties.get( 1904 NETWORK_RESTORE_DELAY_PROP_NAME); 1905 if(restoreDefaultNetworkDelayStr != null && 1906 restoreDefaultNetworkDelayStr.length() != 0) { 1907 try { 1908 return Integer.parseInt(restoreDefaultNetworkDelayStr); 1909 } catch (NumberFormatException e) { 1910 } 1911 } 1912 // if the system property isn't set, use the value for the apn type 1913 int ret = RESTORE_DEFAULT_NETWORK_DELAY; 1914 1915 if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) && 1916 (mNetConfigs[networkType] != null)) { 1917 ret = mNetConfigs[networkType].restoreTime; 1918 } 1919 return ret; 1920 } 1921 argsContain(String[] args, String target)1922 private boolean argsContain(String[] args, String target) { 1923 for (String arg : args) { 1924 if (arg.equals(target)) return true; 1925 } 1926 return false; 1927 } 1928 dumpNetworkDiagnostics(IndentingPrintWriter pw)1929 private void dumpNetworkDiagnostics(IndentingPrintWriter pw) { 1930 final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>(); 1931 final long DIAG_TIME_MS = 5000; 1932 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 1933 // Start gathering diagnostic information. 1934 netDiags.add(new NetworkDiagnostics( 1935 nai.network, 1936 new LinkProperties(nai.linkProperties), // Must be a copy. 1937 DIAG_TIME_MS)); 1938 } 1939 1940 for (NetworkDiagnostics netDiag : netDiags) { 1941 pw.println(); 1942 netDiag.waitForMeasurements(); 1943 netDiag.dump(pw); 1944 } 1945 } 1946 1947 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)1948 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 1949 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 1950 if (mContext.checkCallingOrSelfPermission( 1951 android.Manifest.permission.DUMP) 1952 != PackageManager.PERMISSION_GRANTED) { 1953 pw.println("Permission Denial: can't dump ConnectivityService " + 1954 "from from pid=" + Binder.getCallingPid() + ", uid=" + 1955 Binder.getCallingUid()); 1956 return; 1957 } 1958 1959 if (argsContain(args, "--diag")) { 1960 dumpNetworkDiagnostics(pw); 1961 return; 1962 } 1963 1964 pw.print("NetworkFactories for:"); 1965 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { 1966 pw.print(" " + nfi.name); 1967 } 1968 pw.println(); 1969 pw.println(); 1970 1971 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 1972 pw.print("Active default network: "); 1973 if (defaultNai == null) { 1974 pw.println("none"); 1975 } else { 1976 pw.println(defaultNai.network.netId); 1977 } 1978 pw.println(); 1979 1980 pw.println("Current Networks:"); 1981 pw.increaseIndent(); 1982 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 1983 pw.println(nai.toString()); 1984 pw.increaseIndent(); 1985 pw.println(String.format("Requests: %d request/%d total", 1986 nai.numRequestNetworkRequests(), nai.numNetworkRequests())); 1987 pw.increaseIndent(); 1988 for (int i = 0; i < nai.numNetworkRequests(); i++) { 1989 pw.println(nai.requestAt(i).toString()); 1990 } 1991 pw.decreaseIndent(); 1992 pw.println("Lingered:"); 1993 pw.increaseIndent(); 1994 nai.dumpLingerTimers(pw); 1995 pw.decreaseIndent(); 1996 pw.decreaseIndent(); 1997 } 1998 pw.decreaseIndent(); 1999 pw.println(); 2000 2001 pw.println("Metered Interfaces:"); 2002 pw.increaseIndent(); 2003 for (String value : mMeteredIfaces) { 2004 pw.println(value); 2005 } 2006 pw.decreaseIndent(); 2007 pw.println(); 2008 2009 pw.print("Restrict background: "); 2010 pw.println(mRestrictBackground); 2011 pw.println(); 2012 2013 pw.println("Status for known UIDs:"); 2014 pw.increaseIndent(); 2015 final int size = mUidRules.size(); 2016 for (int i = 0; i < size; i++) { 2017 final int uid = mUidRules.keyAt(i); 2018 pw.print("UID="); 2019 pw.print(uid); 2020 final int uidRules = mUidRules.get(uid, RULE_NONE); 2021 pw.print(" rules="); 2022 pw.print(uidRulesToString(uidRules)); 2023 pw.println(); 2024 } 2025 pw.println(); 2026 pw.decreaseIndent(); 2027 2028 pw.println("Network Requests:"); 2029 pw.increaseIndent(); 2030 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 2031 pw.println(nri.toString()); 2032 } 2033 pw.println(); 2034 pw.decreaseIndent(); 2035 2036 mLegacyTypeTracker.dump(pw); 2037 2038 synchronized (this) { 2039 pw.print("mNetTransitionWakeLock: currently " + 2040 (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held"); 2041 if (!TextUtils.isEmpty(mNetTransitionWakeLockCausedBy)) { 2042 pw.println(", last requested for " + mNetTransitionWakeLockCausedBy); 2043 } else { 2044 pw.println(", last requested never"); 2045 } 2046 } 2047 2048 pw.println(); 2049 mTethering.dump(fd, pw, args); 2050 2051 pw.println(); 2052 mKeepaliveTracker.dump(pw); 2053 2054 pw.println(); 2055 dumpAvoidBadWifiSettings(pw); 2056 2057 pw.println(); 2058 if (mInetLog != null && mInetLog.size() > 0) { 2059 pw.println(); 2060 pw.println("Inet condition reports:"); 2061 pw.increaseIndent(); 2062 for(int i = 0; i < mInetLog.size(); i++) { 2063 pw.println(mInetLog.get(i)); 2064 } 2065 pw.decreaseIndent(); 2066 } 2067 2068 if (argsContain(args, "--short") == false) { 2069 pw.println(); 2070 synchronized (mValidationLogs) { 2071 pw.println("mValidationLogs (most recent first):"); 2072 for (ValidationLog p : mValidationLogs) { 2073 pw.println(p.mNetwork + " - " + p.mNetworkExtraInfo); 2074 pw.increaseIndent(); 2075 p.mLog.dump(fd, pw, args); 2076 pw.decreaseIndent(); 2077 } 2078 } 2079 2080 pw.println(); 2081 pw.println("mNetworkRequestInfoLogs (most recent first):"); 2082 pw.increaseIndent(); 2083 mNetworkRequestInfoLogs.reverseDump(fd, pw, args); 2084 pw.decreaseIndent(); 2085 2086 pw.println(); 2087 pw.println("mNetworkInfoBlockingLogs (most recent first):"); 2088 pw.increaseIndent(); 2089 mNetworkInfoBlockingLogs.reverseDump(fd, pw, args); 2090 pw.decreaseIndent(); 2091 } 2092 } 2093 isLiveNetworkAgent(NetworkAgentInfo nai, int what)2094 private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) { 2095 if (nai.network == null) return false; 2096 final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network); 2097 if (officialNai != null && officialNai.equals(nai)) return true; 2098 if (officialNai != null || VDBG) { 2099 final String msg = sMagicDecoderRing.get(what, Integer.toString(what)); 2100 loge(msg + " - isLiveNetworkAgent found mismatched netId: " + officialNai + 2101 " - " + nai); 2102 } 2103 return false; 2104 } 2105 2106 // must be stateless - things change under us. 2107 private class NetworkStateTrackerHandler extends Handler { NetworkStateTrackerHandler(Looper looper)2108 public NetworkStateTrackerHandler(Looper looper) { 2109 super(looper); 2110 } 2111 maybeHandleAsyncChannelMessage(Message msg)2112 private boolean maybeHandleAsyncChannelMessage(Message msg) { 2113 switch (msg.what) { 2114 default: 2115 return false; 2116 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { 2117 handleAsyncChannelHalfConnect(msg); 2118 break; 2119 } 2120 case AsyncChannel.CMD_CHANNEL_DISCONNECT: { 2121 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); 2122 if (nai != null) nai.asyncChannel.disconnect(); 2123 break; 2124 } 2125 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { 2126 handleAsyncChannelDisconnected(msg); 2127 break; 2128 } 2129 } 2130 return true; 2131 } 2132 maybeHandleNetworkAgentMessage(Message msg)2133 private void maybeHandleNetworkAgentMessage(Message msg) { 2134 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); 2135 if (nai == null) { 2136 if (VDBG) { 2137 final String what = sMagicDecoderRing.get(msg.what, Integer.toString(msg.what)); 2138 log(String.format("%s from unknown NetworkAgent", what)); 2139 } 2140 return; 2141 } 2142 2143 switch (msg.what) { 2144 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: { 2145 final NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj; 2146 if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL) || 2147 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { 2148 Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability."); 2149 } 2150 if (nai.everConnected && !nai.networkCapabilities.equalImmutableCapabilities( 2151 networkCapabilities)) { 2152 Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities: " 2153 + nai.networkCapabilities + " -> " + networkCapabilities); 2154 } 2155 updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities); 2156 break; 2157 } 2158 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: { 2159 if (VDBG) { 2160 log("Update of LinkProperties for " + nai.name() + 2161 "; created=" + nai.created + 2162 "; everConnected=" + nai.everConnected); 2163 } 2164 LinkProperties oldLp = nai.linkProperties; 2165 synchronized (nai) { 2166 nai.linkProperties = (LinkProperties)msg.obj; 2167 } 2168 if (nai.everConnected) updateLinkProperties(nai, oldLp); 2169 break; 2170 } 2171 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: { 2172 NetworkInfo info = (NetworkInfo) msg.obj; 2173 updateNetworkInfo(nai, info); 2174 break; 2175 } 2176 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: { 2177 Integer score = (Integer) msg.obj; 2178 if (score != null) updateNetworkScore(nai, score.intValue()); 2179 break; 2180 } 2181 case NetworkAgent.EVENT_UID_RANGES_ADDED: { 2182 try { 2183 mNetd.addVpnUidRanges(nai.network.netId, (UidRange[])msg.obj); 2184 } catch (Exception e) { 2185 // Never crash! 2186 loge("Exception in addVpnUidRanges: " + e); 2187 } 2188 break; 2189 } 2190 case NetworkAgent.EVENT_UID_RANGES_REMOVED: { 2191 try { 2192 mNetd.removeVpnUidRanges(nai.network.netId, (UidRange[])msg.obj); 2193 } catch (Exception e) { 2194 // Never crash! 2195 loge("Exception in removeVpnUidRanges: " + e); 2196 } 2197 break; 2198 } 2199 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: { 2200 if (nai.everConnected && !nai.networkMisc.explicitlySelected) { 2201 loge("ERROR: already-connected network explicitly selected."); 2202 } 2203 nai.networkMisc.explicitlySelected = true; 2204 nai.networkMisc.acceptUnvalidated = (boolean) msg.obj; 2205 break; 2206 } 2207 case NetworkAgent.EVENT_PACKET_KEEPALIVE: { 2208 mKeepaliveTracker.handleEventPacketKeepalive(nai, msg); 2209 break; 2210 } 2211 } 2212 } 2213 maybeHandleNetworkMonitorMessage(Message msg)2214 private boolean maybeHandleNetworkMonitorMessage(Message msg) { 2215 switch (msg.what) { 2216 default: 2217 return false; 2218 case NetworkMonitor.EVENT_NETWORK_TESTED: { 2219 final NetworkAgentInfo nai; 2220 synchronized (mNetworkForNetId) { 2221 nai = mNetworkForNetId.get(msg.arg2); 2222 } 2223 if (nai != null) { 2224 final boolean valid = 2225 (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID); 2226 final boolean wasValidated = nai.lastValidated; 2227 if (DBG) log(nai.name() + " validation " + (valid ? "passed" : "failed") + 2228 (msg.obj == null ? "" : " with redirect to " + (String)msg.obj)); 2229 if (valid != nai.lastValidated) { 2230 final int oldScore = nai.getCurrentScore(); 2231 nai.lastValidated = valid; 2232 nai.everValidated |= valid; 2233 updateCapabilities(oldScore, nai, nai.networkCapabilities); 2234 // If score has changed, rebroadcast to NetworkFactories. b/17726566 2235 if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai); 2236 } 2237 updateInetCondition(nai); 2238 // Let the NetworkAgent know the state of its network 2239 Bundle redirectUrlBundle = new Bundle(); 2240 redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, (String)msg.obj); 2241 nai.asyncChannel.sendMessage( 2242 NetworkAgent.CMD_REPORT_NETWORK_STATUS, 2243 (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK), 2244 0, redirectUrlBundle); 2245 if (wasValidated && !nai.lastValidated) { 2246 handleNetworkUnvalidated(nai); 2247 } 2248 } 2249 break; 2250 } 2251 case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: { 2252 final int netId = msg.arg2; 2253 final boolean visible = (msg.arg1 != 0); 2254 final NetworkAgentInfo nai; 2255 synchronized (mNetworkForNetId) { 2256 nai = mNetworkForNetId.get(netId); 2257 } 2258 // If captive portal status has changed, update capabilities. 2259 if (nai != null && (visible != nai.lastCaptivePortalDetected)) { 2260 final int oldScore = nai.getCurrentScore(); 2261 nai.lastCaptivePortalDetected = visible; 2262 nai.everCaptivePortalDetected |= visible; 2263 updateCapabilities(oldScore, nai, nai.networkCapabilities); 2264 } 2265 if (!visible) { 2266 mNotifier.clearNotification(netId); 2267 } else { 2268 if (nai == null) { 2269 loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); 2270 break; 2271 } 2272 if (!nai.networkMisc.provisioningNotificationDisabled) { 2273 mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null, 2274 (PendingIntent) msg.obj, nai.networkMisc.explicitlySelected); 2275 } 2276 } 2277 break; 2278 } 2279 } 2280 return true; 2281 } 2282 maybeHandleNetworkAgentInfoMessage(Message msg)2283 private boolean maybeHandleNetworkAgentInfoMessage(Message msg) { 2284 switch (msg.what) { 2285 default: 2286 return false; 2287 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: { 2288 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj; 2289 if (nai != null && isLiveNetworkAgent(nai, msg.what)) { 2290 handleLingerComplete(nai); 2291 } 2292 break; 2293 } 2294 } 2295 return true; 2296 } 2297 2298 @Override handleMessage(Message msg)2299 public void handleMessage(Message msg) { 2300 if (!maybeHandleAsyncChannelMessage(msg) && 2301 !maybeHandleNetworkMonitorMessage(msg) && 2302 !maybeHandleNetworkAgentInfoMessage(msg)) { 2303 maybeHandleNetworkAgentMessage(msg); 2304 } 2305 } 2306 } 2307 updateLingerState(NetworkAgentInfo nai, long now)2308 private void updateLingerState(NetworkAgentInfo nai, long now) { 2309 // 1. Update the linger timer. If it's changed, reschedule or cancel the alarm. 2310 // 2. If the network was lingering and there are now requests, unlinger it. 2311 // 3. If this network is unneeded (which implies it is not lingering), and there is at least 2312 // one lingered request, start lingering. 2313 nai.updateLingerTimer(); 2314 if (nai.isLingering() && nai.numRequestNetworkRequests() > 0) { 2315 if (DBG) log("Unlingering " + nai.name()); 2316 nai.unlinger(); 2317 logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER); 2318 } else if (unneeded(nai) && nai.getLingerExpiry() > 0) { // unneeded() calls isLingering() 2319 int lingerTime = (int) (nai.getLingerExpiry() - now); 2320 if (DBG) { 2321 Log.d(TAG, "Lingering " + nai.name() + " for " + lingerTime + "ms"); 2322 } 2323 nai.linger(); 2324 logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER); 2325 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime); 2326 } 2327 } 2328 handleAsyncChannelHalfConnect(Message msg)2329 private void handleAsyncChannelHalfConnect(Message msg) { 2330 AsyncChannel ac = (AsyncChannel) msg.obj; 2331 if (mNetworkFactoryInfos.containsKey(msg.replyTo)) { 2332 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 2333 if (VDBG) log("NetworkFactory connected"); 2334 // A network factory has connected. Send it all current NetworkRequests. 2335 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 2336 if (nri.request.isListen()) continue; 2337 NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId); 2338 ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, 2339 (nai != null ? nai.getCurrentScore() : 0), 0, nri.request); 2340 } 2341 } else { 2342 loge("Error connecting NetworkFactory"); 2343 mNetworkFactoryInfos.remove(msg.obj); 2344 } 2345 } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) { 2346 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 2347 if (VDBG) log("NetworkAgent connected"); 2348 // A network agent has requested a connection. Establish the connection. 2349 mNetworkAgentInfos.get(msg.replyTo).asyncChannel. 2350 sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 2351 } else { 2352 loge("Error connecting NetworkAgent"); 2353 NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo); 2354 if (nai != null) { 2355 final boolean wasDefault = isDefaultNetwork(nai); 2356 synchronized (mNetworkForNetId) { 2357 mNetworkForNetId.remove(nai.network.netId); 2358 mNetIdInUse.delete(nai.network.netId); 2359 } 2360 // Just in case. 2361 mLegacyTypeTracker.remove(nai, wasDefault); 2362 } 2363 } 2364 } 2365 } 2366 handleAsyncChannelDisconnected(Message msg)2367 private void handleAsyncChannelDisconnected(Message msg) { 2368 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); 2369 if (nai != null) { 2370 if (DBG) { 2371 log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests()); 2372 } 2373 // A network agent has disconnected. 2374 // TODO - if we move the logic to the network agent (have them disconnect 2375 // because they lost all their requests or because their score isn't good) 2376 // then they would disconnect organically, report their new state and then 2377 // disconnect the channel. 2378 if (nai.networkInfo.isConnected()) { 2379 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, 2380 null, null); 2381 } 2382 final boolean wasDefault = isDefaultNetwork(nai); 2383 if (wasDefault) { 2384 mDefaultInetConditionPublished = 0; 2385 // Log default network disconnection before required book-keeping. 2386 // Let rematchAllNetworksAndRequests() below record a new default network event 2387 // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence 2388 // whose timestamps tell how long it takes to recover a default network. 2389 logDefaultNetworkEvent(null, nai); 2390 } 2391 notifyIfacesChangedForNetworkStats(); 2392 // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied 2393 // by other networks that are already connected. Perhaps that can be done by 2394 // sending all CALLBACK_LOST messages (for requests, not listens) at the end 2395 // of rematchAllNetworksAndRequests 2396 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST); 2397 mKeepaliveTracker.handleStopAllKeepalives(nai, 2398 ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK); 2399 nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED); 2400 mNetworkAgentInfos.remove(msg.replyTo); 2401 updateClat(null, nai.linkProperties, nai); 2402 synchronized (mNetworkForNetId) { 2403 // Remove the NetworkAgent, but don't mark the netId as 2404 // available until we've told netd to delete it below. 2405 mNetworkForNetId.remove(nai.network.netId); 2406 } 2407 // Remove all previously satisfied requests. 2408 for (int i = 0; i < nai.numNetworkRequests(); i++) { 2409 NetworkRequest request = nai.requestAt(i); 2410 NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId); 2411 if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) { 2412 mNetworkForRequestId.remove(request.requestId); 2413 sendUpdatedScoreToFactories(request, 0); 2414 } 2415 } 2416 nai.clearLingerState(); 2417 if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) { 2418 removeDataActivityTracking(nai); 2419 notifyLockdownVpn(nai); 2420 requestNetworkTransitionWakelock(nai.name()); 2421 } 2422 mLegacyTypeTracker.remove(nai, wasDefault); 2423 rematchAllNetworksAndRequests(null, 0); 2424 mLingerMonitor.noteDisconnect(nai); 2425 if (nai.created) { 2426 // Tell netd to clean up the configuration for this network 2427 // (routing rules, DNS, etc). 2428 // This may be slow as it requires a lot of netd shelling out to ip and 2429 // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it 2430 // after we've rematched networks with requests which should make a potential 2431 // fallback network the default or requested a new network from the 2432 // NetworkFactories, so network traffic isn't interrupted for an unnecessarily 2433 // long time. 2434 try { 2435 mNetd.removeNetwork(nai.network.netId); 2436 } catch (Exception e) { 2437 loge("Exception removing network: " + e); 2438 } 2439 } 2440 synchronized (mNetworkForNetId) { 2441 mNetIdInUse.delete(nai.network.netId); 2442 } 2443 } else { 2444 NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo); 2445 if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name); 2446 } 2447 } 2448 2449 // If this method proves to be too slow then we can maintain a separate 2450 // pendingIntent => NetworkRequestInfo map. 2451 // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo. findExistingNetworkRequestInfo(PendingIntent pendingIntent)2452 private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) { 2453 Intent intent = pendingIntent.getIntent(); 2454 for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) { 2455 PendingIntent existingPendingIntent = entry.getValue().mPendingIntent; 2456 if (existingPendingIntent != null && 2457 existingPendingIntent.getIntent().filterEquals(intent)) { 2458 return entry.getValue(); 2459 } 2460 } 2461 return null; 2462 } 2463 handleRegisterNetworkRequestWithIntent(Message msg)2464 private void handleRegisterNetworkRequestWithIntent(Message msg) { 2465 final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj); 2466 2467 NetworkRequestInfo existingRequest = findExistingNetworkRequestInfo(nri.mPendingIntent); 2468 if (existingRequest != null) { // remove the existing request. 2469 if (DBG) log("Replacing " + existingRequest.request + " with " 2470 + nri.request + " because their intents matched."); 2471 handleReleaseNetworkRequest(existingRequest.request, getCallingUid()); 2472 } 2473 handleRegisterNetworkRequest(nri); 2474 } 2475 handleRegisterNetworkRequest(NetworkRequestInfo nri)2476 private void handleRegisterNetworkRequest(NetworkRequestInfo nri) { 2477 mNetworkRequests.put(nri.request, nri); 2478 mNetworkRequestInfoLogs.log("REGISTER " + nri); 2479 if (nri.request.isListen()) { 2480 for (NetworkAgentInfo network : mNetworkAgentInfos.values()) { 2481 if (nri.request.networkCapabilities.hasSignalStrength() && 2482 network.satisfiesImmutableCapabilitiesOf(nri.request)) { 2483 updateSignalStrengthThresholds(network, "REGISTER", nri.request); 2484 } 2485 } 2486 } 2487 rematchAllNetworksAndRequests(null, 0); 2488 if (nri.request.isRequest() && mNetworkForRequestId.get(nri.request.requestId) == null) { 2489 sendUpdatedScoreToFactories(nri.request, 0); 2490 } 2491 } 2492 handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent, int callingUid)2493 private void handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent, 2494 int callingUid) { 2495 NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent); 2496 if (nri != null) { 2497 handleReleaseNetworkRequest(nri.request, callingUid); 2498 } 2499 } 2500 2501 // Is nai unneeded by all NetworkRequests (and should be disconnected)? 2502 // This is whether it is satisfying any NetworkRequests or were it to become validated, 2503 // would it have a chance of satisfying any NetworkRequests. unneeded(NetworkAgentInfo nai)2504 private boolean unneeded(NetworkAgentInfo nai) { 2505 if (!nai.everConnected || nai.isVPN() || 2506 nai.isLingering() || nai.numRequestNetworkRequests() > 0) { 2507 return false; 2508 } 2509 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 2510 // If this Network is already the highest scoring Network for a request, or if 2511 // there is hope for it to become one if it validated, then it is needed. 2512 if (nri.request.isRequest() && nai.satisfies(nri.request) && 2513 (nai.isSatisfyingRequest(nri.request.requestId) || 2514 // Note that this catches two important cases: 2515 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi 2516 // is currently satisfying the request. This is desirable when 2517 // cellular ends up validating but WiFi does not. 2518 // 2. Unvalidated WiFi will not be reaped when validated cellular 2519 // is currently satisfying the request. This is desirable when 2520 // WiFi ends up validating and out scoring cellular. 2521 mNetworkForRequestId.get(nri.request.requestId).getCurrentScore() < 2522 nai.getCurrentScoreAsValidated())) { 2523 return false; 2524 } 2525 } 2526 return true; 2527 } 2528 getNriForAppRequest( NetworkRequest request, int callingUid, String requestedOperation)2529 private NetworkRequestInfo getNriForAppRequest( 2530 NetworkRequest request, int callingUid, String requestedOperation) { 2531 final NetworkRequestInfo nri = mNetworkRequests.get(request); 2532 2533 if (nri != null) { 2534 if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) { 2535 log(String.format("UID %d attempted to %s for unowned request %s", 2536 callingUid, requestedOperation, nri)); 2537 return null; 2538 } 2539 } 2540 2541 return nri; 2542 } 2543 handleRequestCallbackUpdate(NetworkRequest request, int callingUid, String description, int callbackType)2544 private void handleRequestCallbackUpdate(NetworkRequest request, int callingUid, 2545 String description, int callbackType) { 2546 final NetworkRequestInfo nri = getNriForAppRequest(request, callingUid, description); 2547 if (nri == null) return; 2548 2549 final NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId); 2550 // The network that is satisfying this request may have changed since 2551 // the application requested the update. 2552 // 2553 // - If the request is no longer satisfied, don't send any updates. 2554 // - If the request is satisfied by a different network, it is the 2555 // caller's responsibility to check that the Network object in the 2556 // callback matches the network that was returned in the last 2557 // onAvailable() callback for this request. 2558 if (nai == null) return; 2559 callCallbackForRequest(nri, nai, callbackType, 0); 2560 } 2561 handleRequestLinkProperties(NetworkRequest request, int callingUid)2562 private void handleRequestLinkProperties(NetworkRequest request, int callingUid) { 2563 handleRequestCallbackUpdate(request, callingUid, 2564 "request LinkProperties", ConnectivityManager.CALLBACK_IP_CHANGED); 2565 } 2566 handleRequestNetworkCapabilities(NetworkRequest request, int callingUid)2567 private void handleRequestNetworkCapabilities(NetworkRequest request, int callingUid) { 2568 handleRequestCallbackUpdate(request, callingUid, 2569 "request NetworkCapabilities", ConnectivityManager.CALLBACK_CAP_CHANGED); 2570 } 2571 handleReleaseNetworkRequest(NetworkRequest request, int callingUid)2572 private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) { 2573 final NetworkRequestInfo nri = getNriForAppRequest( 2574 request, callingUid, "release NetworkRequest"); 2575 if (nri == null) return; 2576 2577 if (VDBG || (DBG && nri.request.isRequest())) log("releasing " + request); 2578 nri.unlinkDeathRecipient(); 2579 mNetworkRequests.remove(request); 2580 synchronized (mUidToNetworkRequestCount) { 2581 int requests = mUidToNetworkRequestCount.get(nri.mUid, 0); 2582 if (requests < 1) { 2583 Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " + 2584 nri.mUid); 2585 } else if (requests == 1) { 2586 mUidToNetworkRequestCount.removeAt( 2587 mUidToNetworkRequestCount.indexOfKey(nri.mUid)); 2588 } else { 2589 mUidToNetworkRequestCount.put(nri.mUid, requests - 1); 2590 } 2591 } 2592 mNetworkRequestInfoLogs.log("RELEASE " + nri); 2593 if (nri.request.isRequest()) { 2594 boolean wasKept = false; 2595 NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId); 2596 if (nai != null) { 2597 nai.removeRequest(nri.request.requestId); 2598 if (VDBG) { 2599 log(" Removing from current network " + nai.name() + 2600 ", leaving " + nai.numNetworkRequests() + " requests."); 2601 } 2602 // If there are still lingered requests on this network, don't tear it down, 2603 // but resume lingering instead. 2604 updateLingerState(nai, SystemClock.elapsedRealtime()); 2605 if (unneeded(nai)) { 2606 if (DBG) log("no live requests for " + nai.name() + "; disconnecting"); 2607 teardownUnneededNetwork(nai); 2608 } else { 2609 wasKept = true; 2610 } 2611 mNetworkForRequestId.remove(nri.request.requestId); 2612 } 2613 2614 // TODO: remove this code once we know that the Slog.wtf is never hit. 2615 // 2616 // Find all networks that are satisfying this request and remove the request 2617 // from their request lists. 2618 // TODO - it's my understanding that for a request there is only a single 2619 // network satisfying it, so this loop is wasteful 2620 for (NetworkAgentInfo otherNai : mNetworkAgentInfos.values()) { 2621 if (otherNai.isSatisfyingRequest(nri.request.requestId) && otherNai != nai) { 2622 Slog.wtf(TAG, "Request " + nri.request + " satisfied by " + 2623 otherNai.name() + ", but mNetworkAgentInfos says " + 2624 (nai != null ? nai.name() : "null")); 2625 } 2626 } 2627 2628 // Maintain the illusion. When this request arrived, we might have pretended 2629 // that a network connected to serve it, even though the network was already 2630 // connected. Now that this request has gone away, we might have to pretend 2631 // that the network disconnected. LegacyTypeTracker will generate that 2632 // phantom disconnect for this type. 2633 if (nri.request.legacyType != TYPE_NONE && nai != null) { 2634 boolean doRemove = true; 2635 if (wasKept) { 2636 // check if any of the remaining requests for this network are for the 2637 // same legacy type - if so, don't remove the nai 2638 for (int i = 0; i < nai.numNetworkRequests(); i++) { 2639 NetworkRequest otherRequest = nai.requestAt(i); 2640 if (otherRequest.legacyType == nri.request.legacyType && 2641 otherRequest.isRequest()) { 2642 if (DBG) log(" still have other legacy request - leaving"); 2643 doRemove = false; 2644 } 2645 } 2646 } 2647 2648 if (doRemove) { 2649 mLegacyTypeTracker.remove(nri.request.legacyType, nai, false); 2650 } 2651 } 2652 2653 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { 2654 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, 2655 nri.request); 2656 } 2657 } else { 2658 // listens don't have a singular affectedNetwork. Check all networks to see 2659 // if this listen request applies and remove it. 2660 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 2661 nai.removeRequest(nri.request.requestId); 2662 if (nri.request.networkCapabilities.hasSignalStrength() && 2663 nai.satisfiesImmutableCapabilitiesOf(nri.request)) { 2664 updateSignalStrengthThresholds(nai, "RELEASE", nri.request); 2665 } 2666 } 2667 } 2668 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED, 0); 2669 } 2670 2671 @Override setAcceptUnvalidated(Network network, boolean accept, boolean always)2672 public void setAcceptUnvalidated(Network network, boolean accept, boolean always) { 2673 enforceConnectivityInternalPermission(); 2674 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED, 2675 accept ? 1 : 0, always ? 1: 0, network)); 2676 } 2677 2678 @Override setAvoidUnvalidated(Network network)2679 public void setAvoidUnvalidated(Network network) { 2680 enforceConnectivityInternalPermission(); 2681 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network)); 2682 } 2683 handleSetAcceptUnvalidated(Network network, boolean accept, boolean always)2684 private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) { 2685 if (DBG) log("handleSetAcceptUnvalidated network=" + network + 2686 " accept=" + accept + " always=" + always); 2687 2688 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2689 if (nai == null) { 2690 // Nothing to do. 2691 return; 2692 } 2693 2694 if (nai.everValidated) { 2695 // The network validated while the dialog box was up. Take no action. 2696 return; 2697 } 2698 2699 if (!nai.networkMisc.explicitlySelected) { 2700 Slog.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network"); 2701 } 2702 2703 if (accept != nai.networkMisc.acceptUnvalidated) { 2704 int oldScore = nai.getCurrentScore(); 2705 nai.networkMisc.acceptUnvalidated = accept; 2706 rematchAllNetworksAndRequests(nai, oldScore); 2707 sendUpdatedScoreToFactories(nai); 2708 } 2709 2710 if (always) { 2711 nai.asyncChannel.sendMessage( 2712 NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, accept ? 1 : 0); 2713 } 2714 2715 if (!accept) { 2716 // Tell the NetworkAgent to not automatically reconnect to the network. 2717 nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); 2718 // Teardown the nework. 2719 teardownUnneededNetwork(nai); 2720 } 2721 2722 } 2723 handleSetAvoidUnvalidated(Network network)2724 private void handleSetAvoidUnvalidated(Network network) { 2725 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2726 if (nai == null || nai.lastValidated) { 2727 // Nothing to do. The network either disconnected or revalidated. 2728 return; 2729 } 2730 if (!nai.avoidUnvalidated) { 2731 int oldScore = nai.getCurrentScore(); 2732 nai.avoidUnvalidated = true; 2733 rematchAllNetworksAndRequests(nai, oldScore); 2734 sendUpdatedScoreToFactories(nai); 2735 } 2736 } 2737 scheduleUnvalidatedPrompt(NetworkAgentInfo nai)2738 private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) { 2739 if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network); 2740 mHandler.sendMessageDelayed( 2741 mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network), 2742 PROMPT_UNVALIDATED_DELAY_MS); 2743 } 2744 avoidBadWifi()2745 public boolean avoidBadWifi() { 2746 return mAvoidBadWifiTracker.currentValue(); 2747 } 2748 rematchForAvoidBadWifiUpdate()2749 private void rematchForAvoidBadWifiUpdate() { 2750 rematchAllNetworksAndRequests(null, 0); 2751 for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) { 2752 if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 2753 sendUpdatedScoreToFactories(nai); 2754 } 2755 } 2756 } 2757 2758 // TODO: Evaluate whether this is of interest to other consumers of 2759 // AvoidBadWifiTracker and worth moving out of here. dumpAvoidBadWifiSettings(IndentingPrintWriter pw)2760 private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) { 2761 final boolean configRestrict = mAvoidBadWifiTracker.configRestrictsAvoidBadWifi(); 2762 if (!configRestrict) { 2763 pw.println("Bad Wi-Fi avoidance: unrestricted"); 2764 return; 2765 } 2766 2767 pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi()); 2768 pw.increaseIndent(); 2769 pw.println("Config restrict: " + configRestrict); 2770 2771 final String value = mAvoidBadWifiTracker.getSettingsValue(); 2772 String description; 2773 // Can't use a switch statement because strings are legal case labels, but null is not. 2774 if ("0".equals(value)) { 2775 description = "get stuck"; 2776 } else if (value == null) { 2777 description = "prompt"; 2778 } else if ("1".equals(value)) { 2779 description = "avoid"; 2780 } else { 2781 description = value + " (?)"; 2782 } 2783 pw.println("User setting: " + description); 2784 pw.println("Network overrides:"); 2785 pw.increaseIndent(); 2786 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 2787 if (nai.avoidUnvalidated) { 2788 pw.println(nai.name()); 2789 } 2790 } 2791 pw.decreaseIndent(); 2792 pw.decreaseIndent(); 2793 } 2794 showValidationNotification(NetworkAgentInfo nai, NotificationType type)2795 private void showValidationNotification(NetworkAgentInfo nai, NotificationType type) { 2796 final String action; 2797 switch (type) { 2798 case NO_INTERNET: 2799 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED; 2800 break; 2801 case LOST_INTERNET: 2802 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION; 2803 break; 2804 default: 2805 Slog.wtf(TAG, "Unknown notification type " + type); 2806 return; 2807 } 2808 2809 Intent intent = new Intent(action); 2810 intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null)); 2811 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2812 intent.setClassName("com.android.settings", 2813 "com.android.settings.wifi.WifiNoInternetDialog"); 2814 2815 PendingIntent pendingIntent = PendingIntent.getActivityAsUser( 2816 mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 2817 mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, true); 2818 } 2819 handlePromptUnvalidated(Network network)2820 private void handlePromptUnvalidated(Network network) { 2821 if (VDBG) log("handlePromptUnvalidated " + network); 2822 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2823 2824 // Only prompt if the network is unvalidated and was explicitly selected by the user, and if 2825 // we haven't already been told to switch to it regardless of whether it validated or not. 2826 // Also don't prompt on captive portals because we're already prompting the user to sign in. 2827 if (nai == null || nai.everValidated || nai.everCaptivePortalDetected || 2828 !nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) { 2829 return; 2830 } 2831 showValidationNotification(nai, NotificationType.NO_INTERNET); 2832 } 2833 handleNetworkUnvalidated(NetworkAgentInfo nai)2834 private void handleNetworkUnvalidated(NetworkAgentInfo nai) { 2835 NetworkCapabilities nc = nai.networkCapabilities; 2836 if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc); 2837 2838 if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && 2839 mAvoidBadWifiTracker.shouldNotifyWifiUnvalidated()) { 2840 showValidationNotification(nai, NotificationType.LOST_INTERNET); 2841 } 2842 } 2843 2844 private class InternalHandler extends Handler { InternalHandler(Looper looper)2845 public InternalHandler(Looper looper) { 2846 super(looper); 2847 } 2848 2849 @Override handleMessage(Message msg)2850 public void handleMessage(Message msg) { 2851 switch (msg.what) { 2852 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK: 2853 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: { 2854 String causedBy = null; 2855 synchronized (ConnectivityService.this) { 2856 if (msg.arg1 == mNetTransitionWakeLockSerialNumber && 2857 mNetTransitionWakeLock.isHeld()) { 2858 mNetTransitionWakeLock.release(); 2859 causedBy = mNetTransitionWakeLockCausedBy; 2860 } else { 2861 break; 2862 } 2863 } 2864 if (VDBG) { 2865 if (msg.what == EVENT_EXPIRE_NET_TRANSITION_WAKELOCK) { 2866 log("Failed to find a new network - expiring NetTransition Wakelock"); 2867 } else { 2868 log("NetTransition Wakelock (" + 2869 (causedBy == null ? "unknown" : causedBy) + 2870 " cleared because we found a replacement network"); 2871 } 2872 } 2873 break; 2874 } 2875 case EVENT_APPLY_GLOBAL_HTTP_PROXY: { 2876 handleDeprecatedGlobalHttpProxy(); 2877 break; 2878 } 2879 case EVENT_PROXY_HAS_CHANGED: { 2880 handleApplyDefaultProxy((ProxyInfo)msg.obj); 2881 break; 2882 } 2883 case EVENT_REGISTER_NETWORK_FACTORY: { 2884 handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj); 2885 break; 2886 } 2887 case EVENT_UNREGISTER_NETWORK_FACTORY: { 2888 handleUnregisterNetworkFactory((Messenger)msg.obj); 2889 break; 2890 } 2891 case EVENT_REGISTER_NETWORK_AGENT: { 2892 handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj); 2893 break; 2894 } 2895 case EVENT_REGISTER_NETWORK_REQUEST: 2896 case EVENT_REGISTER_NETWORK_LISTENER: { 2897 handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj); 2898 break; 2899 } 2900 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: 2901 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: { 2902 handleRegisterNetworkRequestWithIntent(msg); 2903 break; 2904 } 2905 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: { 2906 handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1); 2907 break; 2908 } 2909 case EVENT_RELEASE_NETWORK_REQUEST: { 2910 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1); 2911 break; 2912 } 2913 case EVENT_SET_ACCEPT_UNVALIDATED: { 2914 handleSetAcceptUnvalidated((Network) msg.obj, msg.arg1 != 0, msg.arg2 != 0); 2915 break; 2916 } 2917 case EVENT_SET_AVOID_UNVALIDATED: { 2918 handleSetAvoidUnvalidated((Network) msg.obj); 2919 break; 2920 } 2921 case EVENT_PROMPT_UNVALIDATED: { 2922 handlePromptUnvalidated((Network) msg.obj); 2923 break; 2924 } 2925 case EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON: { 2926 handleMobileDataAlwaysOn(); 2927 break; 2928 } 2929 case EVENT_REQUEST_LINKPROPERTIES: 2930 handleRequestLinkProperties((NetworkRequest) msg.obj, msg.arg1); 2931 break; 2932 case EVENT_REQUEST_NETCAPABILITIES: 2933 handleRequestNetworkCapabilities((NetworkRequest) msg.obj, msg.arg1); 2934 break; 2935 // Sent by KeepaliveTracker to process an app request on the state machine thread. 2936 case NetworkAgent.CMD_START_PACKET_KEEPALIVE: { 2937 mKeepaliveTracker.handleStartKeepalive(msg); 2938 break; 2939 } 2940 // Sent by KeepaliveTracker to process an app request on the state machine thread. 2941 case NetworkAgent.CMD_STOP_PACKET_KEEPALIVE: { 2942 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj); 2943 int slot = msg.arg1; 2944 int reason = msg.arg2; 2945 mKeepaliveTracker.handleStopKeepalive(nai, slot, reason); 2946 break; 2947 } 2948 case EVENT_SYSTEM_READY: { 2949 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 2950 nai.networkMonitor.systemReady = true; 2951 } 2952 break; 2953 } 2954 } 2955 } 2956 } 2957 2958 // javadoc from interface 2959 @Override tether(String iface)2960 public int tether(String iface) { 2961 ConnectivityManager.enforceTetherChangePermission(mContext); 2962 if (isTetheringSupported()) { 2963 final int status = mTethering.tether(iface); 2964 if (status == ConnectivityManager.TETHER_ERROR_NO_ERROR) { 2965 try { 2966 mPolicyManager.onTetheringChanged(iface, true); 2967 } catch (RemoteException e) { 2968 } 2969 } 2970 return status; 2971 } else { 2972 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 2973 } 2974 } 2975 2976 // javadoc from interface 2977 @Override untether(String iface)2978 public int untether(String iface) { 2979 ConnectivityManager.enforceTetherChangePermission(mContext); 2980 2981 if (isTetheringSupported()) { 2982 final int status = mTethering.untether(iface); 2983 if (status == ConnectivityManager.TETHER_ERROR_NO_ERROR) { 2984 try { 2985 mPolicyManager.onTetheringChanged(iface, false); 2986 } catch (RemoteException e) { 2987 } 2988 } 2989 return status; 2990 } else { 2991 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 2992 } 2993 } 2994 2995 // javadoc from interface 2996 @Override getLastTetherError(String iface)2997 public int getLastTetherError(String iface) { 2998 enforceTetherAccessPermission(); 2999 3000 if (isTetheringSupported()) { 3001 return mTethering.getLastTetherError(iface); 3002 } else { 3003 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3004 } 3005 } 3006 3007 // TODO - proper iface API for selection by property, inspection, etc 3008 @Override getTetherableUsbRegexs()3009 public String[] getTetherableUsbRegexs() { 3010 enforceTetherAccessPermission(); 3011 if (isTetheringSupported()) { 3012 return mTethering.getTetherableUsbRegexs(); 3013 } else { 3014 return new String[0]; 3015 } 3016 } 3017 3018 @Override getTetherableWifiRegexs()3019 public String[] getTetherableWifiRegexs() { 3020 enforceTetherAccessPermission(); 3021 if (isTetheringSupported()) { 3022 return mTethering.getTetherableWifiRegexs(); 3023 } else { 3024 return new String[0]; 3025 } 3026 } 3027 3028 @Override getTetherableBluetoothRegexs()3029 public String[] getTetherableBluetoothRegexs() { 3030 enforceTetherAccessPermission(); 3031 if (isTetheringSupported()) { 3032 return mTethering.getTetherableBluetoothRegexs(); 3033 } else { 3034 return new String[0]; 3035 } 3036 } 3037 3038 @Override setUsbTethering(boolean enable)3039 public int setUsbTethering(boolean enable) { 3040 ConnectivityManager.enforceTetherChangePermission(mContext); 3041 if (isTetheringSupported()) { 3042 return mTethering.setUsbTethering(enable); 3043 } else { 3044 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3045 } 3046 } 3047 3048 // TODO - move iface listing, queries, etc to new module 3049 // javadoc from interface 3050 @Override getTetherableIfaces()3051 public String[] getTetherableIfaces() { 3052 enforceTetherAccessPermission(); 3053 return mTethering.getTetherableIfaces(); 3054 } 3055 3056 @Override getTetheredIfaces()3057 public String[] getTetheredIfaces() { 3058 enforceTetherAccessPermission(); 3059 return mTethering.getTetheredIfaces(); 3060 } 3061 3062 @Override getTetheringErroredIfaces()3063 public String[] getTetheringErroredIfaces() { 3064 enforceTetherAccessPermission(); 3065 return mTethering.getErroredIfaces(); 3066 } 3067 3068 @Override getTetheredDhcpRanges()3069 public String[] getTetheredDhcpRanges() { 3070 enforceConnectivityInternalPermission(); 3071 return mTethering.getTetheredDhcpRanges(); 3072 } 3073 3074 // if ro.tether.denied = true we default to no tethering 3075 // gservices could set the secure setting to 1 though to enable it on a build where it 3076 // had previously been turned off. 3077 @Override isTetheringSupported()3078 public boolean isTetheringSupported() { 3079 enforceTetherAccessPermission(); 3080 int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1); 3081 boolean tetherEnabledInSettings = (Settings.Global.getInt(mContext.getContentResolver(), 3082 Settings.Global.TETHER_SUPPORTED, defaultVal) != 0) 3083 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING); 3084 return tetherEnabledInSettings && mUserManager.isAdminUser() && 3085 ((mTethering.getTetherableUsbRegexs().length != 0 || 3086 mTethering.getTetherableWifiRegexs().length != 0 || 3087 mTethering.getTetherableBluetoothRegexs().length != 0) && 3088 mTethering.getUpstreamIfaceTypes().length != 0); 3089 } 3090 3091 @Override startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi)3092 public void startTethering(int type, ResultReceiver receiver, 3093 boolean showProvisioningUi) { 3094 ConnectivityManager.enforceTetherChangePermission(mContext); 3095 if (!isTetheringSupported()) { 3096 receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null); 3097 return; 3098 } 3099 mTethering.startTethering(type, receiver, showProvisioningUi); 3100 } 3101 3102 @Override stopTethering(int type)3103 public void stopTethering(int type) { 3104 ConnectivityManager.enforceTetherChangePermission(mContext); 3105 mTethering.stopTethering(type); 3106 } 3107 3108 // Called when we lose the default network and have no replacement yet. 3109 // This will automatically be cleared after X seconds or a new default network 3110 // becomes CONNECTED, whichever happens first. The timer is started by the 3111 // first caller and not restarted by subsequent callers. requestNetworkTransitionWakelock(String forWhom)3112 private void requestNetworkTransitionWakelock(String forWhom) { 3113 int serialNum = 0; 3114 synchronized (this) { 3115 if (mNetTransitionWakeLock.isHeld()) return; 3116 serialNum = ++mNetTransitionWakeLockSerialNumber; 3117 mNetTransitionWakeLock.acquire(); 3118 mNetTransitionWakeLockCausedBy = forWhom; 3119 } 3120 mHandler.sendMessageDelayed(mHandler.obtainMessage( 3121 EVENT_EXPIRE_NET_TRANSITION_WAKELOCK, serialNum, 0), 3122 mNetTransitionWakeLockTimeout); 3123 return; 3124 } 3125 3126 // 100 percent is full good, 0 is full bad. 3127 @Override reportInetCondition(int networkType, int percentage)3128 public void reportInetCondition(int networkType, int percentage) { 3129 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 3130 if (nai == null) return; 3131 reportNetworkConnectivity(nai.network, percentage > 50); 3132 } 3133 3134 @Override reportNetworkConnectivity(Network network, boolean hasConnectivity)3135 public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { 3136 enforceAccessPermission(); 3137 enforceInternetPermission(); 3138 3139 NetworkAgentInfo nai; 3140 if (network == null) { 3141 nai = getDefaultNetwork(); 3142 } else { 3143 nai = getNetworkAgentInfoForNetwork(network); 3144 } 3145 if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING || 3146 nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) { 3147 return; 3148 } 3149 // Revalidate if the app report does not match our current validated state. 3150 if (hasConnectivity == nai.lastValidated) return; 3151 final int uid = Binder.getCallingUid(); 3152 if (DBG) { 3153 log("reportNetworkConnectivity(" + nai.network.netId + ", " + hasConnectivity + 3154 ") by " + uid); 3155 } 3156 synchronized (nai) { 3157 // Validating a network that has not yet connected could result in a call to 3158 // rematchNetworkAndRequests() which is not meant to work on such networks. 3159 if (!nai.everConnected) return; 3160 3161 if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, false)) return; 3162 3163 nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid); 3164 } 3165 } 3166 getDefaultProxy()3167 private ProxyInfo getDefaultProxy() { 3168 // this information is already available as a world read/writable jvm property 3169 // so this API change wouldn't have a benifit. It also breaks the passing 3170 // of proxy info to all the JVMs. 3171 // enforceAccessPermission(); 3172 synchronized (mProxyLock) { 3173 ProxyInfo ret = mGlobalProxy; 3174 if ((ret == null) && !mDefaultProxyDisabled) ret = mDefaultProxy; 3175 return ret; 3176 } 3177 } 3178 3179 @Override getProxyForNetwork(Network network)3180 public ProxyInfo getProxyForNetwork(Network network) { 3181 if (network == null) return getDefaultProxy(); 3182 final ProxyInfo globalProxy = getGlobalProxy(); 3183 if (globalProxy != null) return globalProxy; 3184 if (!NetworkUtils.queryUserAccess(Binder.getCallingUid(), network.netId)) return null; 3185 // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which 3186 // caller may not have. 3187 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3188 if (nai == null) return null; 3189 synchronized (nai) { 3190 final ProxyInfo proxyInfo = nai.linkProperties.getHttpProxy(); 3191 if (proxyInfo == null) return null; 3192 return new ProxyInfo(proxyInfo); 3193 } 3194 } 3195 3196 // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present 3197 // (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific 3198 // proxy is null then there is no proxy in place). canonicalizeProxyInfo(ProxyInfo proxy)3199 private ProxyInfo canonicalizeProxyInfo(ProxyInfo proxy) { 3200 if (proxy != null && TextUtils.isEmpty(proxy.getHost()) 3201 && (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) { 3202 proxy = null; 3203 } 3204 return proxy; 3205 } 3206 3207 // ProxyInfo equality function with a couple modifications over ProxyInfo.equals() to make it 3208 // better for determining if a new proxy broadcast is necessary: 3209 // 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to 3210 // avoid unnecessary broadcasts. 3211 // 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL 3212 // is in place. This is important so legacy PAC resolver (see com.android.proxyhandler) 3213 // changes aren't missed. The legacy PAC resolver pretends to be a simple HTTP proxy but 3214 // actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port 3215 // all set. proxyInfoEqual(ProxyInfo a, ProxyInfo b)3216 private boolean proxyInfoEqual(ProxyInfo a, ProxyInfo b) { 3217 a = canonicalizeProxyInfo(a); 3218 b = canonicalizeProxyInfo(b); 3219 // ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check 3220 // hosts even when PAC URLs are present to account for the legacy PAC resolver. 3221 return Objects.equals(a, b) && (a == null || Objects.equals(a.getHost(), b.getHost())); 3222 } 3223 setGlobalProxy(ProxyInfo proxyProperties)3224 public void setGlobalProxy(ProxyInfo proxyProperties) { 3225 enforceConnectivityInternalPermission(); 3226 3227 synchronized (mProxyLock) { 3228 if (proxyProperties == mGlobalProxy) return; 3229 if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return; 3230 if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return; 3231 3232 String host = ""; 3233 int port = 0; 3234 String exclList = ""; 3235 String pacFileUrl = ""; 3236 if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) || 3237 !Uri.EMPTY.equals(proxyProperties.getPacFileUrl()))) { 3238 if (!proxyProperties.isValid()) { 3239 if (DBG) 3240 log("Invalid proxy properties, ignoring: " + proxyProperties.toString()); 3241 return; 3242 } 3243 mGlobalProxy = new ProxyInfo(proxyProperties); 3244 host = mGlobalProxy.getHost(); 3245 port = mGlobalProxy.getPort(); 3246 exclList = mGlobalProxy.getExclusionListAsString(); 3247 if (!Uri.EMPTY.equals(proxyProperties.getPacFileUrl())) { 3248 pacFileUrl = proxyProperties.getPacFileUrl().toString(); 3249 } 3250 } else { 3251 mGlobalProxy = null; 3252 } 3253 ContentResolver res = mContext.getContentResolver(); 3254 final long token = Binder.clearCallingIdentity(); 3255 try { 3256 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host); 3257 Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port); 3258 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST, 3259 exclList); 3260 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl); 3261 } finally { 3262 Binder.restoreCallingIdentity(token); 3263 } 3264 3265 if (mGlobalProxy == null) { 3266 proxyProperties = mDefaultProxy; 3267 } 3268 sendProxyBroadcast(proxyProperties); 3269 } 3270 } 3271 loadGlobalProxy()3272 private void loadGlobalProxy() { 3273 ContentResolver res = mContext.getContentResolver(); 3274 String host = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST); 3275 int port = Settings.Global.getInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, 0); 3276 String exclList = Settings.Global.getString(res, 3277 Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST); 3278 String pacFileUrl = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC); 3279 if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) { 3280 ProxyInfo proxyProperties; 3281 if (!TextUtils.isEmpty(pacFileUrl)) { 3282 proxyProperties = new ProxyInfo(pacFileUrl); 3283 } else { 3284 proxyProperties = new ProxyInfo(host, port, exclList); 3285 } 3286 if (!proxyProperties.isValid()) { 3287 if (DBG) log("Invalid proxy properties, ignoring: " + proxyProperties.toString()); 3288 return; 3289 } 3290 3291 synchronized (mProxyLock) { 3292 mGlobalProxy = proxyProperties; 3293 } 3294 } 3295 } 3296 getGlobalProxy()3297 public ProxyInfo getGlobalProxy() { 3298 // this information is already available as a world read/writable jvm property 3299 // so this API change wouldn't have a benifit. It also breaks the passing 3300 // of proxy info to all the JVMs. 3301 // enforceAccessPermission(); 3302 synchronized (mProxyLock) { 3303 return mGlobalProxy; 3304 } 3305 } 3306 handleApplyDefaultProxy(ProxyInfo proxy)3307 private void handleApplyDefaultProxy(ProxyInfo proxy) { 3308 if (proxy != null && TextUtils.isEmpty(proxy.getHost()) 3309 && Uri.EMPTY.equals(proxy.getPacFileUrl())) { 3310 proxy = null; 3311 } 3312 synchronized (mProxyLock) { 3313 if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return; 3314 if (mDefaultProxy == proxy) return; // catches repeated nulls 3315 if (proxy != null && !proxy.isValid()) { 3316 if (DBG) log("Invalid proxy properties, ignoring: " + proxy.toString()); 3317 return; 3318 } 3319 3320 // This call could be coming from the PacManager, containing the port of the local 3321 // proxy. If this new proxy matches the global proxy then copy this proxy to the 3322 // global (to get the correct local port), and send a broadcast. 3323 // TODO: Switch PacManager to have its own message to send back rather than 3324 // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy. 3325 if ((mGlobalProxy != null) && (proxy != null) 3326 && (!Uri.EMPTY.equals(proxy.getPacFileUrl())) 3327 && proxy.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) { 3328 mGlobalProxy = proxy; 3329 sendProxyBroadcast(mGlobalProxy); 3330 return; 3331 } 3332 mDefaultProxy = proxy; 3333 3334 if (mGlobalProxy != null) return; 3335 if (!mDefaultProxyDisabled) { 3336 sendProxyBroadcast(proxy); 3337 } 3338 } 3339 } 3340 3341 // If the proxy has changed from oldLp to newLp, resend proxy broadcast with default proxy. 3342 // This method gets called when any network changes proxy, but the broadcast only ever contains 3343 // the default proxy (even if it hasn't changed). 3344 // TODO: Deprecate the broadcast extras as they aren't necessarily applicable in a multi-network 3345 // world where an app might be bound to a non-default network. updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai)3346 private void updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) { 3347 ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy(); 3348 ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy(); 3349 3350 if (!proxyInfoEqual(newProxyInfo, oldProxyInfo)) { 3351 sendProxyBroadcast(getDefaultProxy()); 3352 } 3353 } 3354 handleDeprecatedGlobalHttpProxy()3355 private void handleDeprecatedGlobalHttpProxy() { 3356 String proxy = Settings.Global.getString(mContext.getContentResolver(), 3357 Settings.Global.HTTP_PROXY); 3358 if (!TextUtils.isEmpty(proxy)) { 3359 String data[] = proxy.split(":"); 3360 if (data.length == 0) { 3361 return; 3362 } 3363 3364 String proxyHost = data[0]; 3365 int proxyPort = 8080; 3366 if (data.length > 1) { 3367 try { 3368 proxyPort = Integer.parseInt(data[1]); 3369 } catch (NumberFormatException e) { 3370 return; 3371 } 3372 } 3373 ProxyInfo p = new ProxyInfo(data[0], proxyPort, ""); 3374 setGlobalProxy(p); 3375 } 3376 } 3377 sendProxyBroadcast(ProxyInfo proxy)3378 private void sendProxyBroadcast(ProxyInfo proxy) { 3379 if (proxy == null) proxy = new ProxyInfo("", 0, ""); 3380 if (mPacManager.setCurrentProxyScriptUrl(proxy)) return; 3381 if (DBG) log("sending Proxy Broadcast for " + proxy); 3382 Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); 3383 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | 3384 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3385 intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy); 3386 final long ident = Binder.clearCallingIdentity(); 3387 try { 3388 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 3389 } finally { 3390 Binder.restoreCallingIdentity(ident); 3391 } 3392 } 3393 3394 private static class SettingsObserver extends ContentObserver { 3395 final private HashMap<Uri, Integer> mUriEventMap; 3396 final private Context mContext; 3397 final private Handler mHandler; 3398 SettingsObserver(Context context, Handler handler)3399 SettingsObserver(Context context, Handler handler) { 3400 super(null); 3401 mUriEventMap = new HashMap<Uri, Integer>(); 3402 mContext = context; 3403 mHandler = handler; 3404 } 3405 observe(Uri uri, int what)3406 void observe(Uri uri, int what) { 3407 mUriEventMap.put(uri, what); 3408 final ContentResolver resolver = mContext.getContentResolver(); 3409 resolver.registerContentObserver(uri, false, this); 3410 } 3411 3412 @Override onChange(boolean selfChange)3413 public void onChange(boolean selfChange) { 3414 Slog.wtf(TAG, "Should never be reached."); 3415 } 3416 3417 @Override onChange(boolean selfChange, Uri uri)3418 public void onChange(boolean selfChange, Uri uri) { 3419 final Integer what = mUriEventMap.get(uri); 3420 if (what != null) { 3421 mHandler.obtainMessage(what.intValue()).sendToTarget(); 3422 } else { 3423 loge("No matching event to send for URI=" + uri); 3424 } 3425 } 3426 } 3427 log(String s)3428 private static void log(String s) { 3429 Slog.d(TAG, s); 3430 } 3431 loge(String s)3432 private static void loge(String s) { 3433 Slog.e(TAG, s); 3434 } 3435 checkNotNull(T value, String message)3436 private static <T> T checkNotNull(T value, String message) { 3437 if (value == null) { 3438 throw new NullPointerException(message); 3439 } 3440 return value; 3441 } 3442 3443 /** 3444 * Prepare for a VPN application. 3445 * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId}, 3446 * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required. 3447 * 3448 * @param oldPackage Package name of the application which currently controls VPN, which will 3449 * be replaced. If there is no such application, this should should either be 3450 * {@code null} or {@link VpnConfig.LEGACY_VPN}. 3451 * @param newPackage Package name of the application which should gain control of VPN, or 3452 * {@code null} to disable. 3453 * @param userId User for whom to prepare the new VPN. 3454 * 3455 * @hide 3456 */ 3457 @Override prepareVpn(@ullable String oldPackage, @Nullable String newPackage, int userId)3458 public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage, 3459 int userId) { 3460 enforceCrossUserPermission(userId); 3461 throwIfLockdownEnabled(); 3462 3463 synchronized(mVpns) { 3464 Vpn vpn = mVpns.get(userId); 3465 if (vpn != null) { 3466 return vpn.prepare(oldPackage, newPackage); 3467 } else { 3468 return false; 3469 } 3470 } 3471 } 3472 3473 /** 3474 * Set whether the VPN package has the ability to launch VPNs without user intervention. 3475 * This method is used by system-privileged apps. 3476 * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId}, 3477 * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required. 3478 * 3479 * @param packageName The package for which authorization state should change. 3480 * @param userId User for whom {@code packageName} is installed. 3481 * @param authorized {@code true} if this app should be able to start a VPN connection without 3482 * explicit user approval, {@code false} if not. 3483 * 3484 * @hide 3485 */ 3486 @Override setVpnPackageAuthorization(String packageName, int userId, boolean authorized)3487 public void setVpnPackageAuthorization(String packageName, int userId, boolean authorized) { 3488 enforceCrossUserPermission(userId); 3489 3490 synchronized(mVpns) { 3491 Vpn vpn = mVpns.get(userId); 3492 if (vpn != null) { 3493 vpn.setPackageAuthorization(packageName, authorized); 3494 } 3495 } 3496 } 3497 3498 /** 3499 * Configure a TUN interface and return its file descriptor. Parameters 3500 * are encoded and opaque to this class. This method is used by VpnBuilder 3501 * and not available in ConnectivityManager. Permissions are checked in 3502 * Vpn class. 3503 * @hide 3504 */ 3505 @Override establishVpn(VpnConfig config)3506 public ParcelFileDescriptor establishVpn(VpnConfig config) { 3507 throwIfLockdownEnabled(); 3508 int user = UserHandle.getUserId(Binder.getCallingUid()); 3509 synchronized(mVpns) { 3510 return mVpns.get(user).establish(config); 3511 } 3512 } 3513 3514 /** 3515 * Start legacy VPN, controlling native daemons as needed. Creates a 3516 * secondary thread to perform connection work, returning quickly. 3517 */ 3518 @Override startLegacyVpn(VpnProfile profile)3519 public void startLegacyVpn(VpnProfile profile) { 3520 throwIfLockdownEnabled(); 3521 final LinkProperties egress = getActiveLinkProperties(); 3522 if (egress == null) { 3523 throw new IllegalStateException("Missing active network connection"); 3524 } 3525 int user = UserHandle.getUserId(Binder.getCallingUid()); 3526 synchronized(mVpns) { 3527 mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress); 3528 } 3529 } 3530 3531 /** 3532 * Return the information of the ongoing legacy VPN. This method is used 3533 * by VpnSettings and not available in ConnectivityManager. Permissions 3534 * are checked in Vpn class. 3535 */ 3536 @Override getLegacyVpnInfo(int userId)3537 public LegacyVpnInfo getLegacyVpnInfo(int userId) { 3538 enforceCrossUserPermission(userId); 3539 3540 synchronized(mVpns) { 3541 return mVpns.get(userId).getLegacyVpnInfo(); 3542 } 3543 } 3544 3545 /** 3546 * Return the information of all ongoing VPNs. This method is used by NetworkStatsService 3547 * and not available in ConnectivityManager. 3548 */ 3549 @Override getAllVpnInfo()3550 public VpnInfo[] getAllVpnInfo() { 3551 enforceConnectivityInternalPermission(); 3552 if (mLockdownEnabled) { 3553 return new VpnInfo[0]; 3554 } 3555 3556 synchronized(mVpns) { 3557 List<VpnInfo> infoList = new ArrayList<>(); 3558 for (int i = 0; i < mVpns.size(); i++) { 3559 VpnInfo info = createVpnInfo(mVpns.valueAt(i)); 3560 if (info != null) { 3561 infoList.add(info); 3562 } 3563 } 3564 return infoList.toArray(new VpnInfo[infoList.size()]); 3565 } 3566 } 3567 3568 /** 3569 * @return VPN information for accounting, or null if we can't retrieve all required 3570 * information, e.g primary underlying iface. 3571 */ 3572 @Nullable createVpnInfo(Vpn vpn)3573 private VpnInfo createVpnInfo(Vpn vpn) { 3574 VpnInfo info = vpn.getVpnInfo(); 3575 if (info == null) { 3576 return null; 3577 } 3578 Network[] underlyingNetworks = vpn.getUnderlyingNetworks(); 3579 // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret 3580 // the underlyingNetworks list. 3581 if (underlyingNetworks == null) { 3582 NetworkAgentInfo defaultNetwork = getDefaultNetwork(); 3583 if (defaultNetwork != null && defaultNetwork.linkProperties != null) { 3584 info.primaryUnderlyingIface = getDefaultNetwork().linkProperties.getInterfaceName(); 3585 } 3586 } else if (underlyingNetworks.length > 0) { 3587 LinkProperties linkProperties = getLinkProperties(underlyingNetworks[0]); 3588 if (linkProperties != null) { 3589 info.primaryUnderlyingIface = linkProperties.getInterfaceName(); 3590 } 3591 } 3592 return info.primaryUnderlyingIface == null ? null : info; 3593 } 3594 3595 /** 3596 * Returns the information of the ongoing VPN for {@code userId}. This method is used by 3597 * VpnDialogs and not available in ConnectivityManager. 3598 * Permissions are checked in Vpn class. 3599 * @hide 3600 */ 3601 @Override getVpnConfig(int userId)3602 public VpnConfig getVpnConfig(int userId) { 3603 enforceCrossUserPermission(userId); 3604 synchronized(mVpns) { 3605 Vpn vpn = mVpns.get(userId); 3606 if (vpn != null) { 3607 return vpn.getVpnConfig(); 3608 } else { 3609 return null; 3610 } 3611 } 3612 } 3613 3614 @Override updateLockdownVpn()3615 public boolean updateLockdownVpn() { 3616 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 3617 Slog.w(TAG, "Lockdown VPN only available to AID_SYSTEM"); 3618 return false; 3619 } 3620 3621 // Tear down existing lockdown if profile was removed 3622 mLockdownEnabled = LockdownVpnTracker.isEnabled(); 3623 if (mLockdownEnabled) { 3624 final String profileName = new String(mKeyStore.get(Credentials.LOCKDOWN_VPN)); 3625 final VpnProfile profile = VpnProfile.decode( 3626 profileName, mKeyStore.get(Credentials.VPN + profileName)); 3627 if (profile == null) { 3628 Slog.e(TAG, "Lockdown VPN configured invalid profile " + profileName); 3629 setLockdownTracker(null); 3630 return true; 3631 } 3632 int user = UserHandle.getUserId(Binder.getCallingUid()); 3633 synchronized(mVpns) { 3634 Vpn vpn = mVpns.get(user); 3635 if (vpn == null) { 3636 Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown"); 3637 return false; 3638 } 3639 setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, vpn, profile)); 3640 } 3641 } else { 3642 setLockdownTracker(null); 3643 } 3644 3645 return true; 3646 } 3647 3648 /** 3649 * Internally set new {@link LockdownVpnTracker}, shutting down any existing 3650 * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown. 3651 */ setLockdownTracker(LockdownVpnTracker tracker)3652 private void setLockdownTracker(LockdownVpnTracker tracker) { 3653 // Shutdown any existing tracker 3654 final LockdownVpnTracker existing = mLockdownTracker; 3655 mLockdownTracker = null; 3656 if (existing != null) { 3657 existing.shutdown(); 3658 } 3659 3660 try { 3661 if (tracker != null) { 3662 mNetd.setFirewallEnabled(true); 3663 mNetd.setFirewallInterfaceRule("lo", true); 3664 mLockdownTracker = tracker; 3665 mLockdownTracker.init(); 3666 } else { 3667 mNetd.setFirewallEnabled(false); 3668 } 3669 } catch (RemoteException e) { 3670 // ignored; NMS lives inside system_server 3671 } 3672 } 3673 throwIfLockdownEnabled()3674 private void throwIfLockdownEnabled() { 3675 if (mLockdownEnabled) { 3676 throw new IllegalStateException("Unavailable in lockdown mode"); 3677 } 3678 } 3679 3680 /** 3681 * Starts the always-on VPN {@link VpnService} for user {@param userId}, which should perform 3682 * some setup and then call {@code establish()} to connect. 3683 * 3684 * @return {@code true} if the service was started, the service was already connected, or there 3685 * was no always-on VPN to start. {@code false} otherwise. 3686 */ startAlwaysOnVpn(int userId)3687 private boolean startAlwaysOnVpn(int userId) { 3688 synchronized (mVpns) { 3689 Vpn vpn = mVpns.get(userId); 3690 if (vpn == null) { 3691 // Shouldn't happen as all codepaths that point here should have checked the Vpn 3692 // exists already. 3693 Slog.wtf(TAG, "User " + userId + " has no Vpn configuration"); 3694 return false; 3695 } 3696 3697 return vpn.startAlwaysOnVpn(); 3698 } 3699 } 3700 3701 @Override setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown)3702 public boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown) { 3703 enforceConnectivityInternalPermission(); 3704 enforceCrossUserPermission(userId); 3705 3706 // Can't set always-on VPN if legacy VPN is already in lockdown mode. 3707 if (LockdownVpnTracker.isEnabled()) { 3708 return false; 3709 } 3710 3711 synchronized (mVpns) { 3712 Vpn vpn = mVpns.get(userId); 3713 if (vpn == null) { 3714 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 3715 return false; 3716 } 3717 if (!vpn.setAlwaysOnPackage(packageName, lockdown)) { 3718 return false; 3719 } 3720 if (!startAlwaysOnVpn(userId)) { 3721 vpn.setAlwaysOnPackage(null, false); 3722 return false; 3723 } 3724 3725 vpn.saveAlwaysOnPackage(); 3726 } 3727 return true; 3728 } 3729 3730 @Override getAlwaysOnVpnPackage(int userId)3731 public String getAlwaysOnVpnPackage(int userId) { 3732 enforceConnectivityInternalPermission(); 3733 enforceCrossUserPermission(userId); 3734 3735 synchronized (mVpns) { 3736 Vpn vpn = mVpns.get(userId); 3737 if (vpn == null) { 3738 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 3739 return null; 3740 } 3741 return vpn.getAlwaysOnPackage(); 3742 } 3743 } 3744 3745 @Override checkMobileProvisioning(int suggestedTimeOutMs)3746 public int checkMobileProvisioning(int suggestedTimeOutMs) { 3747 // TODO: Remove? Any reason to trigger a provisioning check? 3748 return -1; 3749 } 3750 3751 /** Location to an updatable file listing carrier provisioning urls. 3752 * An example: 3753 * 3754 * <?xml version="1.0" encoding="utf-8"?> 3755 * <provisioningUrls> 3756 * <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&iccid=%1$s&imei=%2$s</provisioningUrl> 3757 * </provisioningUrls> 3758 */ 3759 private static final String PROVISIONING_URL_PATH = 3760 "/data/misc/radio/provisioning_urls.xml"; 3761 private final File mProvisioningUrlFile = new File(PROVISIONING_URL_PATH); 3762 3763 /** XML tag for root element. */ 3764 private static final String TAG_PROVISIONING_URLS = "provisioningUrls"; 3765 /** XML tag for individual url */ 3766 private static final String TAG_PROVISIONING_URL = "provisioningUrl"; 3767 /** XML attribute for mcc */ 3768 private static final String ATTR_MCC = "mcc"; 3769 /** XML attribute for mnc */ 3770 private static final String ATTR_MNC = "mnc"; 3771 getProvisioningUrlBaseFromFile()3772 private String getProvisioningUrlBaseFromFile() { 3773 FileReader fileReader = null; 3774 XmlPullParser parser = null; 3775 Configuration config = mContext.getResources().getConfiguration(); 3776 3777 try { 3778 fileReader = new FileReader(mProvisioningUrlFile); 3779 parser = Xml.newPullParser(); 3780 parser.setInput(fileReader); 3781 XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS); 3782 3783 while (true) { 3784 XmlUtils.nextElement(parser); 3785 3786 String element = parser.getName(); 3787 if (element == null) break; 3788 3789 if (element.equals(TAG_PROVISIONING_URL)) { 3790 String mcc = parser.getAttributeValue(null, ATTR_MCC); 3791 try { 3792 if (mcc != null && Integer.parseInt(mcc) == config.mcc) { 3793 String mnc = parser.getAttributeValue(null, ATTR_MNC); 3794 if (mnc != null && Integer.parseInt(mnc) == config.mnc) { 3795 parser.next(); 3796 if (parser.getEventType() == XmlPullParser.TEXT) { 3797 return parser.getText(); 3798 } 3799 } 3800 } 3801 } catch (NumberFormatException e) { 3802 loge("NumberFormatException in getProvisioningUrlBaseFromFile: " + e); 3803 } 3804 } 3805 } 3806 return null; 3807 } catch (FileNotFoundException e) { 3808 loge("Carrier Provisioning Urls file not found"); 3809 } catch (XmlPullParserException e) { 3810 loge("Xml parser exception reading Carrier Provisioning Urls file: " + e); 3811 } catch (IOException e) { 3812 loge("I/O exception reading Carrier Provisioning Urls file: " + e); 3813 } finally { 3814 if (fileReader != null) { 3815 try { 3816 fileReader.close(); 3817 } catch (IOException e) {} 3818 } 3819 } 3820 return null; 3821 } 3822 3823 @Override getMobileProvisioningUrl()3824 public String getMobileProvisioningUrl() { 3825 enforceConnectivityInternalPermission(); 3826 String url = getProvisioningUrlBaseFromFile(); 3827 if (TextUtils.isEmpty(url)) { 3828 url = mContext.getResources().getString(R.string.mobile_provisioning_url); 3829 log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url); 3830 } else { 3831 log("getMobileProvisioningUrl: mobile_provisioning_url from File =" + url); 3832 } 3833 // populate the iccid, imei and phone number in the provisioning url. 3834 if (!TextUtils.isEmpty(url)) { 3835 String phoneNumber = mTelephonyManager.getLine1Number(); 3836 if (TextUtils.isEmpty(phoneNumber)) { 3837 phoneNumber = "0000000000"; 3838 } 3839 url = String.format(url, 3840 mTelephonyManager.getSimSerialNumber() /* ICCID */, 3841 mTelephonyManager.getDeviceId() /* IMEI */, 3842 phoneNumber /* Phone numer */); 3843 } 3844 3845 return url; 3846 } 3847 3848 @Override setProvisioningNotificationVisible(boolean visible, int networkType, String action)3849 public void setProvisioningNotificationVisible(boolean visible, int networkType, 3850 String action) { 3851 enforceConnectivityInternalPermission(); 3852 final long ident = Binder.clearCallingIdentity(); 3853 try { 3854 // Concatenate the range of types onto the range of NetIDs. 3855 int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); 3856 mNotifier.setProvNotificationVisible(visible, id, action); 3857 } finally { 3858 Binder.restoreCallingIdentity(ident); 3859 } 3860 } 3861 3862 @Override setAirplaneMode(boolean enable)3863 public void setAirplaneMode(boolean enable) { 3864 enforceConnectivityInternalPermission(); 3865 final long ident = Binder.clearCallingIdentity(); 3866 try { 3867 final ContentResolver cr = mContext.getContentResolver(); 3868 Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0); 3869 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 3870 intent.putExtra("state", enable); 3871 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3872 } finally { 3873 Binder.restoreCallingIdentity(ident); 3874 } 3875 } 3876 onUserStart(int userId)3877 private void onUserStart(int userId) { 3878 synchronized(mVpns) { 3879 Vpn userVpn = mVpns.get(userId); 3880 if (userVpn != null) { 3881 loge("Starting user already has a VPN"); 3882 return; 3883 } 3884 userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, userId); 3885 mVpns.put(userId, userVpn); 3886 3887 final ContentResolver cr = mContext.getContentResolver(); 3888 String alwaysOnPackage = Settings.Secure.getStringForUser(cr, 3889 Settings.Secure.ALWAYS_ON_VPN_APP, userId); 3890 final boolean alwaysOnLockdown = Settings.Secure.getIntForUser(cr, 3891 Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, /* default */ 0, userId) != 0; 3892 if (alwaysOnPackage != null) { 3893 userVpn.setAlwaysOnPackage(alwaysOnPackage, alwaysOnLockdown); 3894 } 3895 } 3896 if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { 3897 updateLockdownVpn(); 3898 } 3899 } 3900 onUserStop(int userId)3901 private void onUserStop(int userId) { 3902 synchronized(mVpns) { 3903 Vpn userVpn = mVpns.get(userId); 3904 if (userVpn == null) { 3905 loge("Stopped user has no VPN"); 3906 return; 3907 } 3908 userVpn.onUserStopped(); 3909 mVpns.delete(userId); 3910 } 3911 } 3912 onUserAdded(int userId)3913 private void onUserAdded(int userId) { 3914 synchronized(mVpns) { 3915 final int vpnsSize = mVpns.size(); 3916 for (int i = 0; i < vpnsSize; i++) { 3917 Vpn vpn = mVpns.valueAt(i); 3918 vpn.onUserAdded(userId); 3919 } 3920 } 3921 } 3922 onUserRemoved(int userId)3923 private void onUserRemoved(int userId) { 3924 synchronized(mVpns) { 3925 final int vpnsSize = mVpns.size(); 3926 for (int i = 0; i < vpnsSize; i++) { 3927 Vpn vpn = mVpns.valueAt(i); 3928 vpn.onUserRemoved(userId); 3929 } 3930 } 3931 } 3932 onUserUnlocked(int userId)3933 private void onUserUnlocked(int userId) { 3934 // User present may be sent because of an unlock, which might mean an unlocked keystore. 3935 if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { 3936 updateLockdownVpn(); 3937 } else { 3938 startAlwaysOnVpn(userId); 3939 } 3940 } 3941 3942 private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() { 3943 @Override 3944 public void onReceive(Context context, Intent intent) { 3945 final String action = intent.getAction(); 3946 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 3947 if (userId == UserHandle.USER_NULL) return; 3948 3949 if (Intent.ACTION_USER_STARTED.equals(action)) { 3950 onUserStart(userId); 3951 } else if (Intent.ACTION_USER_STOPPED.equals(action)) { 3952 onUserStop(userId); 3953 } else if (Intent.ACTION_USER_ADDED.equals(action)) { 3954 onUserAdded(userId); 3955 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 3956 onUserRemoved(userId); 3957 } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) { 3958 onUserUnlocked(userId); 3959 } 3960 } 3961 }; 3962 3963 private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos = 3964 new HashMap<Messenger, NetworkFactoryInfo>(); 3965 private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = 3966 new HashMap<NetworkRequest, NetworkRequestInfo>(); 3967 3968 private static final int MAX_NETWORK_REQUESTS_PER_UID = 100; 3969 // Map from UID to number of NetworkRequests that UID has filed. 3970 @GuardedBy("mUidToNetworkRequestCount") 3971 private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray(); 3972 3973 private static class NetworkFactoryInfo { 3974 public final String name; 3975 public final Messenger messenger; 3976 public final AsyncChannel asyncChannel; 3977 NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel)3978 public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) { 3979 this.name = name; 3980 this.messenger = messenger; 3981 this.asyncChannel = asyncChannel; 3982 } 3983 } 3984 ensureNetworkRequestHasType(NetworkRequest request)3985 private void ensureNetworkRequestHasType(NetworkRequest request) { 3986 if (request.type == NetworkRequest.Type.NONE) { 3987 throw new IllegalArgumentException( 3988 "All NetworkRequests in ConnectivityService must have a type"); 3989 } 3990 } 3991 3992 /** 3993 * Tracks info about the requester. 3994 * Also used to notice when the calling process dies so we can self-expire 3995 */ 3996 private class NetworkRequestInfo implements IBinder.DeathRecipient { 3997 final NetworkRequest request; 3998 final PendingIntent mPendingIntent; 3999 boolean mPendingIntentSent; 4000 private final IBinder mBinder; 4001 final int mPid; 4002 final int mUid; 4003 final Messenger messenger; 4004 NetworkRequestInfo(NetworkRequest r, PendingIntent pi)4005 NetworkRequestInfo(NetworkRequest r, PendingIntent pi) { 4006 request = r; 4007 ensureNetworkRequestHasType(request); 4008 mPendingIntent = pi; 4009 messenger = null; 4010 mBinder = null; 4011 mPid = getCallingPid(); 4012 mUid = getCallingUid(); 4013 enforceRequestCountLimit(); 4014 } 4015 NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder)4016 NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) { 4017 super(); 4018 messenger = m; 4019 request = r; 4020 ensureNetworkRequestHasType(request); 4021 mBinder = binder; 4022 mPid = getCallingPid(); 4023 mUid = getCallingUid(); 4024 mPendingIntent = null; 4025 enforceRequestCountLimit(); 4026 4027 try { 4028 mBinder.linkToDeath(this, 0); 4029 } catch (RemoteException e) { 4030 binderDied(); 4031 } 4032 } 4033 enforceRequestCountLimit()4034 private void enforceRequestCountLimit() { 4035 synchronized (mUidToNetworkRequestCount) { 4036 int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1; 4037 if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) { 4038 throw new IllegalArgumentException("Too many NetworkRequests filed"); 4039 } 4040 mUidToNetworkRequestCount.put(mUid, networkRequests); 4041 } 4042 } 4043 unlinkDeathRecipient()4044 void unlinkDeathRecipient() { 4045 if (mBinder != null) { 4046 mBinder.unlinkToDeath(this, 0); 4047 } 4048 } 4049 binderDied()4050 public void binderDied() { 4051 log("ConnectivityService NetworkRequestInfo binderDied(" + 4052 request + ", " + mBinder + ")"); 4053 releaseNetworkRequest(request); 4054 } 4055 toString()4056 public String toString() { 4057 return "uid/pid:" + mUid + "/" + mPid + " " + request + 4058 (mPendingIntent == null ? "" : " to trigger " + mPendingIntent); 4059 } 4060 } 4061 ensureRequestableCapabilities(NetworkCapabilities networkCapabilities)4062 private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) { 4063 final String badCapability = networkCapabilities.describeFirstNonRequestableCapability(); 4064 if (badCapability != null) { 4065 throw new IllegalArgumentException("Cannot request network with " + badCapability); 4066 } 4067 } 4068 getSignalStrengthThresholds(NetworkAgentInfo nai)4069 private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) { 4070 final SortedSet<Integer> thresholds = new TreeSet(); 4071 synchronized (nai) { 4072 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 4073 if (nri.request.networkCapabilities.hasSignalStrength() && 4074 nai.satisfiesImmutableCapabilitiesOf(nri.request)) { 4075 thresholds.add(nri.request.networkCapabilities.getSignalStrength()); 4076 } 4077 } 4078 } 4079 return new ArrayList<Integer>(thresholds); 4080 } 4081 updateSignalStrengthThresholds( NetworkAgentInfo nai, String reason, NetworkRequest request)4082 private void updateSignalStrengthThresholds( 4083 NetworkAgentInfo nai, String reason, NetworkRequest request) { 4084 ArrayList<Integer> thresholdsArray = getSignalStrengthThresholds(nai); 4085 Bundle thresholds = new Bundle(); 4086 thresholds.putIntegerArrayList("thresholds", thresholdsArray); 4087 4088 if (VDBG || (DBG && !"CONNECT".equals(reason))) { 4089 String detail; 4090 if (request != null && request.networkCapabilities.hasSignalStrength()) { 4091 detail = reason + " " + request.networkCapabilities.getSignalStrength(); 4092 } else { 4093 detail = reason; 4094 } 4095 log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s", 4096 detail, Arrays.toString(thresholdsArray.toArray()), nai.name())); 4097 } 4098 4099 nai.asyncChannel.sendMessage( 4100 android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS, 4101 0, 0, thresholds); 4102 } 4103 4104 @Override requestNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, int timeoutMs, IBinder binder, int legacyType)4105 public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, 4106 Messenger messenger, int timeoutMs, IBinder binder, int legacyType) { 4107 final NetworkRequest.Type type = (networkCapabilities == null) 4108 ? NetworkRequest.Type.TRACK_DEFAULT 4109 : NetworkRequest.Type.REQUEST; 4110 // If the requested networkCapabilities is null, take them instead from 4111 // the default network request. This allows callers to keep track of 4112 // the system default network. 4113 if (type == NetworkRequest.Type.TRACK_DEFAULT) { 4114 networkCapabilities = new NetworkCapabilities(mDefaultRequest.networkCapabilities); 4115 enforceAccessPermission(); 4116 } else { 4117 networkCapabilities = new NetworkCapabilities(networkCapabilities); 4118 enforceNetworkRequestPermissions(networkCapabilities); 4119 // TODO: this is incorrect. We mark the request as metered or not depending on the state 4120 // of the app when the request is filed, but we never change the request if the app 4121 // changes network state. http://b/29964605 4122 enforceMeteredApnPolicy(networkCapabilities); 4123 } 4124 ensureRequestableCapabilities(networkCapabilities); 4125 4126 if (timeoutMs < 0 || timeoutMs > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS) { 4127 throw new IllegalArgumentException("Bad timeout specified"); 4128 } 4129 4130 if (NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER 4131 .equals(networkCapabilities.getNetworkSpecifier())) { 4132 throw new IllegalArgumentException("Invalid network specifier - must not be '" 4133 + NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER + "'"); 4134 } 4135 4136 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, 4137 nextNetworkRequestId(), type); 4138 NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder); 4139 if (DBG) log("requestNetwork for " + nri); 4140 4141 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri)); 4142 if (timeoutMs > 0) { 4143 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST, 4144 nri), timeoutMs); 4145 } 4146 return networkRequest; 4147 } 4148 enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities)4149 private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) { 4150 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) { 4151 enforceConnectivityRestrictedNetworksPermission(); 4152 } else { 4153 enforceChangePermission(); 4154 } 4155 } 4156 4157 @Override requestBandwidthUpdate(Network network)4158 public boolean requestBandwidthUpdate(Network network) { 4159 enforceAccessPermission(); 4160 NetworkAgentInfo nai = null; 4161 if (network == null) { 4162 return false; 4163 } 4164 synchronized (mNetworkForNetId) { 4165 nai = mNetworkForNetId.get(network.netId); 4166 } 4167 if (nai != null) { 4168 nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE); 4169 return true; 4170 } 4171 return false; 4172 } 4173 isSystem(int uid)4174 private boolean isSystem(int uid) { 4175 return uid < Process.FIRST_APPLICATION_UID; 4176 } 4177 enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities)4178 private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) { 4179 final int uid = Binder.getCallingUid(); 4180 if (isSystem(uid)) { 4181 return; 4182 } 4183 // if UID is restricted, don't allow them to bring up metered APNs 4184 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED) == false) { 4185 final int uidRules; 4186 synchronized(mRulesLock) { 4187 uidRules = mUidRules.get(uid, RULE_ALLOW_ALL); 4188 } 4189 if (mRestrictBackground && (uidRules & RULE_ALLOW_METERED) == 0 4190 && (uidRules & RULE_TEMPORARY_ALLOW_METERED) == 0) { 4191 // we could silently fail or we can filter the available nets to only give 4192 // them those they have access to. Chose the more useful option. 4193 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 4194 } 4195 } 4196 } 4197 4198 @Override pendingRequestForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)4199 public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, 4200 PendingIntent operation) { 4201 checkNotNull(operation, "PendingIntent cannot be null."); 4202 networkCapabilities = new NetworkCapabilities(networkCapabilities); 4203 enforceNetworkRequestPermissions(networkCapabilities); 4204 enforceMeteredApnPolicy(networkCapabilities); 4205 ensureRequestableCapabilities(networkCapabilities); 4206 4207 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, 4208 nextNetworkRequestId(), NetworkRequest.Type.REQUEST); 4209 NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation); 4210 if (DBG) log("pendingRequest for " + nri); 4211 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT, 4212 nri)); 4213 return networkRequest; 4214 } 4215 releasePendingNetworkRequestWithDelay(PendingIntent operation)4216 private void releasePendingNetworkRequestWithDelay(PendingIntent operation) { 4217 mHandler.sendMessageDelayed( 4218 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 4219 getCallingUid(), 0, operation), mReleasePendingIntentDelayMs); 4220 } 4221 4222 @Override releasePendingNetworkRequest(PendingIntent operation)4223 public void releasePendingNetworkRequest(PendingIntent operation) { 4224 checkNotNull(operation, "PendingIntent cannot be null."); 4225 mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 4226 getCallingUid(), 0, operation)); 4227 } 4228 4229 // In order to implement the compatibility measure for pre-M apps that call 4230 // WifiManager.enableNetwork(..., true) without also binding to that network explicitly, 4231 // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork. 4232 // This ensures it has permission to do so. hasWifiNetworkListenPermission(NetworkCapabilities nc)4233 private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) { 4234 if (nc == null) { 4235 return false; 4236 } 4237 int[] transportTypes = nc.getTransportTypes(); 4238 if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) { 4239 return false; 4240 } 4241 try { 4242 mContext.enforceCallingOrSelfPermission( 4243 android.Manifest.permission.ACCESS_WIFI_STATE, 4244 "ConnectivityService"); 4245 } catch (SecurityException e) { 4246 return false; 4247 } 4248 return true; 4249 } 4250 4251 @Override listenForNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, IBinder binder)4252 public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, 4253 Messenger messenger, IBinder binder) { 4254 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 4255 enforceAccessPermission(); 4256 } 4257 4258 NetworkRequest networkRequest = new NetworkRequest( 4259 new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(), 4260 NetworkRequest.Type.LISTEN); 4261 NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder); 4262 if (VDBG) log("listenForNetwork for " + nri); 4263 4264 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); 4265 return networkRequest; 4266 } 4267 4268 @Override pendingListenForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)4269 public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, 4270 PendingIntent operation) { 4271 checkNotNull(operation, "PendingIntent cannot be null."); 4272 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 4273 enforceAccessPermission(); 4274 } 4275 4276 NetworkRequest networkRequest = new NetworkRequest( 4277 new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(), 4278 NetworkRequest.Type.LISTEN); 4279 NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation); 4280 if (VDBG) log("pendingListenForNetwork for " + nri); 4281 4282 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); 4283 } 4284 4285 @Override requestLinkProperties(NetworkRequest networkRequest)4286 public void requestLinkProperties(NetworkRequest networkRequest) { 4287 ensureNetworkRequestHasType(networkRequest); 4288 if (networkRequest.type == NetworkRequest.Type.LISTEN) return; 4289 mHandler.sendMessage(mHandler.obtainMessage( 4290 EVENT_REQUEST_LINKPROPERTIES, getCallingUid(), 0, networkRequest)); 4291 } 4292 4293 @Override requestNetworkCapabilities(NetworkRequest networkRequest)4294 public void requestNetworkCapabilities(NetworkRequest networkRequest) { 4295 ensureNetworkRequestHasType(networkRequest); 4296 if (networkRequest.type == NetworkRequest.Type.LISTEN) return; 4297 mHandler.sendMessage(mHandler.obtainMessage( 4298 EVENT_REQUEST_NETCAPABILITIES, getCallingUid(), 0, networkRequest)); 4299 } 4300 4301 @Override releaseNetworkRequest(NetworkRequest networkRequest)4302 public void releaseNetworkRequest(NetworkRequest networkRequest) { 4303 ensureNetworkRequestHasType(networkRequest); 4304 mHandler.sendMessage(mHandler.obtainMessage( 4305 EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), 0, networkRequest)); 4306 } 4307 4308 @Override registerNetworkFactory(Messenger messenger, String name)4309 public void registerNetworkFactory(Messenger messenger, String name) { 4310 enforceConnectivityInternalPermission(); 4311 NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel()); 4312 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); 4313 } 4314 handleRegisterNetworkFactory(NetworkFactoryInfo nfi)4315 private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { 4316 if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); 4317 mNetworkFactoryInfos.put(nfi.messenger, nfi); 4318 nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger); 4319 } 4320 4321 @Override unregisterNetworkFactory(Messenger messenger)4322 public void unregisterNetworkFactory(Messenger messenger) { 4323 enforceConnectivityInternalPermission(); 4324 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger)); 4325 } 4326 handleUnregisterNetworkFactory(Messenger messenger)4327 private void handleUnregisterNetworkFactory(Messenger messenger) { 4328 NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger); 4329 if (nfi == null) { 4330 loge("Failed to find Messenger in unregisterNetworkFactory"); 4331 return; 4332 } 4333 if (DBG) log("unregisterNetworkFactory for " + nfi.name); 4334 } 4335 4336 /** 4337 * NetworkAgentInfo supporting a request by requestId. 4338 * These have already been vetted (their Capabilities satisfy the request) 4339 * and the are the highest scored network available. 4340 * the are keyed off the Requests requestId. 4341 */ 4342 // TODO: Yikes, this is accessed on multiple threads: add synchronization. 4343 private final SparseArray<NetworkAgentInfo> mNetworkForRequestId = 4344 new SparseArray<NetworkAgentInfo>(); 4345 4346 // NOTE: Accessed on multiple threads, must be synchronized on itself. 4347 @GuardedBy("mNetworkForNetId") 4348 private final SparseArray<NetworkAgentInfo> mNetworkForNetId = 4349 new SparseArray<NetworkAgentInfo>(); 4350 // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId. 4351 // An entry is first added to mNetIdInUse, prior to mNetworkForNetId, so 4352 // there may not be a strict 1:1 correlation between the two. 4353 @GuardedBy("mNetworkForNetId") 4354 private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray(); 4355 4356 // NetworkAgentInfo keyed off its connecting messenger 4357 // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays 4358 // NOTE: Only should be accessed on ConnectivityServiceThread, except dump(). 4359 private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos = 4360 new HashMap<Messenger, NetworkAgentInfo>(); 4361 4362 @GuardedBy("mBlockedAppUids") 4363 private final HashSet<Integer> mBlockedAppUids = new HashSet(); 4364 4365 // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated. 4366 private final NetworkRequest mDefaultRequest; 4367 4368 // Request used to optionally keep mobile data active even when higher 4369 // priority networks like Wi-Fi are active. 4370 private final NetworkRequest mDefaultMobileDataRequest; 4371 getDefaultNetwork()4372 private NetworkAgentInfo getDefaultNetwork() { 4373 return mNetworkForRequestId.get(mDefaultRequest.requestId); 4374 } 4375 isDefaultNetwork(NetworkAgentInfo nai)4376 private boolean isDefaultNetwork(NetworkAgentInfo nai) { 4377 return nai == getDefaultNetwork(); 4378 } 4379 isDefaultRequest(NetworkRequestInfo nri)4380 private boolean isDefaultRequest(NetworkRequestInfo nri) { 4381 return nri.request.requestId == mDefaultRequest.requestId; 4382 } 4383 registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc)4384 public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, 4385 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 4386 int currentScore, NetworkMisc networkMisc) { 4387 enforceConnectivityInternalPermission(); 4388 4389 // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network 4390 // satisfies mDefaultRequest. 4391 final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), 4392 new Network(reserveNetId()), new NetworkInfo(networkInfo), new LinkProperties( 4393 linkProperties), new NetworkCapabilities(networkCapabilities), currentScore, 4394 mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this); 4395 synchronized (this) { 4396 nai.networkMonitor.systemReady = mSystemReady; 4397 } 4398 addValidationLogs(nai.networkMonitor.getValidationLogs(), nai.network, 4399 networkInfo.getExtraInfo()); 4400 if (DBG) log("registerNetworkAgent " + nai); 4401 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai)); 4402 return nai.network.netId; 4403 } 4404 handleRegisterNetworkAgent(NetworkAgentInfo na)4405 private void handleRegisterNetworkAgent(NetworkAgentInfo na) { 4406 if (VDBG) log("Got NetworkAgent Messenger"); 4407 mNetworkAgentInfos.put(na.messenger, na); 4408 synchronized (mNetworkForNetId) { 4409 mNetworkForNetId.put(na.network.netId, na); 4410 } 4411 na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger); 4412 NetworkInfo networkInfo = na.networkInfo; 4413 na.networkInfo = null; 4414 updateNetworkInfo(na, networkInfo); 4415 } 4416 updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp)4417 private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp) { 4418 LinkProperties newLp = networkAgent.linkProperties; 4419 int netId = networkAgent.network.netId; 4420 4421 // The NetworkAgentInfo does not know whether clatd is running on its network or not. Before 4422 // we do anything else, make sure its LinkProperties are accurate. 4423 if (networkAgent.clatd != null) { 4424 networkAgent.clatd.fixupLinkProperties(oldLp); 4425 } 4426 4427 updateInterfaces(newLp, oldLp, netId); 4428 updateMtu(newLp, oldLp); 4429 // TODO - figure out what to do for clat 4430 // for (LinkProperties lp : newLp.getStackedLinks()) { 4431 // updateMtu(lp, null); 4432 // } 4433 updateTcpBufferSizes(networkAgent); 4434 4435 updateRoutes(newLp, oldLp, netId); 4436 updateDnses(newLp, oldLp, netId); 4437 4438 updateClat(newLp, oldLp, networkAgent); 4439 if (isDefaultNetwork(networkAgent)) { 4440 handleApplyDefaultProxy(newLp.getHttpProxy()); 4441 } else { 4442 updateProxy(newLp, oldLp, networkAgent); 4443 } 4444 // TODO - move this check to cover the whole function 4445 if (!Objects.equals(newLp, oldLp)) { 4446 notifyIfacesChangedForNetworkStats(); 4447 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED); 4448 } 4449 4450 mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent); 4451 } 4452 updateClat(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai)4453 private void updateClat(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) { 4454 final boolean wasRunningClat = nai.clatd != null && nai.clatd.isStarted(); 4455 final boolean shouldRunClat = Nat464Xlat.requiresClat(nai); 4456 4457 if (!wasRunningClat && shouldRunClat) { 4458 nai.clatd = new Nat464Xlat(mContext, mNetd, mTrackerHandler, nai); 4459 nai.clatd.start(); 4460 } else if (wasRunningClat && !shouldRunClat) { 4461 nai.clatd.stop(); 4462 } 4463 } 4464 updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId)4465 private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId) { 4466 CompareResult<String> interfaceDiff = new CompareResult<String>(); 4467 if (oldLp != null) { 4468 interfaceDiff = oldLp.compareAllInterfaceNames(newLp); 4469 } else if (newLp != null) { 4470 interfaceDiff.added = newLp.getAllInterfaceNames(); 4471 } 4472 for (String iface : interfaceDiff.added) { 4473 try { 4474 if (DBG) log("Adding iface " + iface + " to network " + netId); 4475 mNetd.addInterfaceToNetwork(iface, netId); 4476 } catch (Exception e) { 4477 loge("Exception adding interface: " + e); 4478 } 4479 } 4480 for (String iface : interfaceDiff.removed) { 4481 try { 4482 if (DBG) log("Removing iface " + iface + " from network " + netId); 4483 mNetd.removeInterfaceFromNetwork(iface, netId); 4484 } catch (Exception e) { 4485 loge("Exception removing interface: " + e); 4486 } 4487 } 4488 } 4489 4490 /** 4491 * Have netd update routes from oldLp to newLp. 4492 * @return true if routes changed between oldLp and newLp 4493 */ updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId)4494 private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) { 4495 CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>(); 4496 if (oldLp != null) { 4497 routeDiff = oldLp.compareAllRoutes(newLp); 4498 } else if (newLp != null) { 4499 routeDiff.added = newLp.getAllRoutes(); 4500 } 4501 4502 // add routes before removing old in case it helps with continuous connectivity 4503 4504 // do this twice, adding non-nexthop routes first, then routes they are dependent on 4505 for (RouteInfo route : routeDiff.added) { 4506 if (route.hasGateway()) continue; 4507 if (VDBG) log("Adding Route [" + route + "] to network " + netId); 4508 try { 4509 mNetd.addRoute(netId, route); 4510 } catch (Exception e) { 4511 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) { 4512 loge("Exception in addRoute for non-gateway: " + e); 4513 } 4514 } 4515 } 4516 for (RouteInfo route : routeDiff.added) { 4517 if (route.hasGateway() == false) continue; 4518 if (VDBG) log("Adding Route [" + route + "] to network " + netId); 4519 try { 4520 mNetd.addRoute(netId, route); 4521 } catch (Exception e) { 4522 if ((route.getGateway() instanceof Inet4Address) || VDBG) { 4523 loge("Exception in addRoute for gateway: " + e); 4524 } 4525 } 4526 } 4527 4528 for (RouteInfo route : routeDiff.removed) { 4529 if (VDBG) log("Removing Route [" + route + "] from network " + netId); 4530 try { 4531 mNetd.removeRoute(netId, route); 4532 } catch (Exception e) { 4533 loge("Exception in removeRoute: " + e); 4534 } 4535 } 4536 return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty(); 4537 } 4538 updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId)4539 private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) { 4540 if (oldLp != null && newLp.isIdenticalDnses(oldLp)) { 4541 return; // no updating necessary 4542 } 4543 4544 Collection<InetAddress> dnses = newLp.getDnsServers(); 4545 if (DBG) log("Setting DNS servers for network " + netId + " to " + dnses); 4546 try { 4547 mNetd.setDnsConfigurationForNetwork( 4548 netId, NetworkUtils.makeStrings(dnses), newLp.getDomains()); 4549 } catch (Exception e) { 4550 loge("Exception in setDnsConfigurationForNetwork: " + e); 4551 } 4552 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 4553 if (defaultNai != null && defaultNai.network.netId == netId) { 4554 setDefaultDnsSystemProperties(dnses); 4555 } 4556 flushVmDnsCache(); 4557 } 4558 setDefaultDnsSystemProperties(Collection<InetAddress> dnses)4559 private void setDefaultDnsSystemProperties(Collection<InetAddress> dnses) { 4560 int last = 0; 4561 for (InetAddress dns : dnses) { 4562 ++last; 4563 String key = "net.dns" + last; 4564 String value = dns.getHostAddress(); 4565 SystemProperties.set(key, value); 4566 } 4567 for (int i = last + 1; i <= mNumDnsEntries; ++i) { 4568 String key = "net.dns" + i; 4569 SystemProperties.set(key, ""); 4570 } 4571 mNumDnsEntries = last; 4572 } 4573 4574 /** 4575 * Update the NetworkCapabilities for {@code networkAgent} to {@code networkCapabilities} 4576 * augmented with any stateful capabilities implied from {@code networkAgent} 4577 * (e.g., validated status and captive portal status). 4578 * 4579 * @param oldScore score of the network before any of the changes that prompted us 4580 * to call this function. 4581 * @param nai the network having its capabilities updated. 4582 * @param networkCapabilities the new network capabilities. 4583 */ updateCapabilities( int oldScore, NetworkAgentInfo nai, NetworkCapabilities networkCapabilities)4584 private void updateCapabilities( 4585 int oldScore, NetworkAgentInfo nai, NetworkCapabilities networkCapabilities) { 4586 // Don't modify caller's NetworkCapabilities. 4587 networkCapabilities = new NetworkCapabilities(networkCapabilities); 4588 if (nai.lastValidated) { 4589 networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED); 4590 } else { 4591 networkCapabilities.removeCapability(NET_CAPABILITY_VALIDATED); 4592 } 4593 if (nai.lastCaptivePortalDetected) { 4594 networkCapabilities.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 4595 } else { 4596 networkCapabilities.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 4597 } 4598 if (!Objects.equals(nai.networkCapabilities, networkCapabilities)) { 4599 if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) != 4600 networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 4601 try { 4602 mNetd.setNetworkPermission(nai.network.netId, 4603 networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) ? 4604 null : NetworkManagementService.PERMISSION_SYSTEM); 4605 } catch (RemoteException e) { 4606 loge("Exception in setNetworkPermission: " + e); 4607 } 4608 } 4609 synchronized (nai) { 4610 nai.networkCapabilities = networkCapabilities; 4611 } 4612 rematchAllNetworksAndRequests(nai, oldScore); 4613 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 4614 } 4615 } 4616 sendUpdatedScoreToFactories(NetworkAgentInfo nai)4617 private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) { 4618 for (int i = 0; i < nai.numNetworkRequests(); i++) { 4619 NetworkRequest nr = nai.requestAt(i); 4620 // Don't send listening requests to factories. b/17393458 4621 if (nr.isListen()) continue; 4622 sendUpdatedScoreToFactories(nr, nai.getCurrentScore()); 4623 } 4624 } 4625 sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score)4626 private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) { 4627 if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString()); 4628 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { 4629 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0, 4630 networkRequest); 4631 } 4632 } 4633 sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType)4634 private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, 4635 int notificationType) { 4636 if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) { 4637 Intent intent = new Intent(); 4638 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network); 4639 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, nri.request); 4640 nri.mPendingIntentSent = true; 4641 sendIntent(nri.mPendingIntent, intent); 4642 } 4643 // else not handled 4644 } 4645 sendIntent(PendingIntent pendingIntent, Intent intent)4646 private void sendIntent(PendingIntent pendingIntent, Intent intent) { 4647 mPendingIntentWakeLock.acquire(); 4648 try { 4649 if (DBG) log("Sending " + pendingIntent); 4650 pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */); 4651 } catch (PendingIntent.CanceledException e) { 4652 if (DBG) log(pendingIntent + " was not sent, it had been canceled."); 4653 mPendingIntentWakeLock.release(); 4654 releasePendingNetworkRequest(pendingIntent); 4655 } 4656 // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished() 4657 } 4658 4659 @Override onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)4660 public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, 4661 String resultData, Bundle resultExtras) { 4662 if (DBG) log("Finished sending " + pendingIntent); 4663 mPendingIntentWakeLock.release(); 4664 // Release with a delay so the receiving client has an opportunity to put in its 4665 // own request. 4666 releasePendingNetworkRequestWithDelay(pendingIntent); 4667 } 4668 callCallbackForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType, int arg1)4669 private void callCallbackForRequest(NetworkRequestInfo nri, 4670 NetworkAgentInfo networkAgent, int notificationType, int arg1) { 4671 if (nri.messenger == null) return; // Default request has no msgr 4672 Bundle bundle = new Bundle(); 4673 bundle.putParcelable(NetworkRequest.class.getSimpleName(), 4674 new NetworkRequest(nri.request)); 4675 Message msg = Message.obtain(); 4676 if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL && 4677 notificationType != ConnectivityManager.CALLBACK_RELEASED) { 4678 bundle.putParcelable(Network.class.getSimpleName(), networkAgent.network); 4679 } 4680 switch (notificationType) { 4681 case ConnectivityManager.CALLBACK_LOSING: { 4682 msg.arg1 = arg1; 4683 break; 4684 } 4685 case ConnectivityManager.CALLBACK_CAP_CHANGED: { 4686 bundle.putParcelable(NetworkCapabilities.class.getSimpleName(), 4687 new NetworkCapabilities(networkAgent.networkCapabilities)); 4688 break; 4689 } 4690 case ConnectivityManager.CALLBACK_IP_CHANGED: { 4691 bundle.putParcelable(LinkProperties.class.getSimpleName(), 4692 new LinkProperties(networkAgent.linkProperties)); 4693 break; 4694 } 4695 } 4696 msg.what = notificationType; 4697 msg.setData(bundle); 4698 try { 4699 if (VDBG) { 4700 log("sending notification " + notifyTypeToName(notificationType) + 4701 " for " + nri.request); 4702 } 4703 nri.messenger.send(msg); 4704 } catch (RemoteException e) { 4705 // may occur naturally in the race of binder death. 4706 loge("RemoteException caught trying to send a callback msg for " + nri.request); 4707 } 4708 } 4709 teardownUnneededNetwork(NetworkAgentInfo nai)4710 private void teardownUnneededNetwork(NetworkAgentInfo nai) { 4711 if (nai.numRequestNetworkRequests() != 0) { 4712 for (int i = 0; i < nai.numNetworkRequests(); i++) { 4713 NetworkRequest nr = nai.requestAt(i); 4714 // Ignore listening requests. 4715 if (nr.isListen()) continue; 4716 loge("Dead network still had at least " + nr); 4717 break; 4718 } 4719 } 4720 nai.asyncChannel.disconnect(); 4721 } 4722 handleLingerComplete(NetworkAgentInfo oldNetwork)4723 private void handleLingerComplete(NetworkAgentInfo oldNetwork) { 4724 if (oldNetwork == null) { 4725 loge("Unknown NetworkAgentInfo in handleLingerComplete"); 4726 return; 4727 } 4728 if (DBG) log("handleLingerComplete for " + oldNetwork.name()); 4729 4730 // If we get here it means that the last linger timeout for this network expired. So there 4731 // must be no other active linger timers, and we must stop lingering. 4732 oldNetwork.clearLingerState(); 4733 4734 if (unneeded(oldNetwork)) { 4735 teardownUnneededNetwork(oldNetwork); 4736 } 4737 } 4738 makeDefault(NetworkAgentInfo newNetwork)4739 private void makeDefault(NetworkAgentInfo newNetwork) { 4740 if (DBG) log("Switching to new default network: " + newNetwork); 4741 setupDataActivityTracking(newNetwork); 4742 try { 4743 mNetd.setDefaultNetId(newNetwork.network.netId); 4744 } catch (Exception e) { 4745 loge("Exception setting default network :" + e); 4746 } 4747 notifyLockdownVpn(newNetwork); 4748 handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy()); 4749 updateTcpBufferSizes(newNetwork); 4750 setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers()); 4751 } 4752 4753 // Handles a network appearing or improving its score. 4754 // 4755 // - Evaluates all current NetworkRequests that can be 4756 // satisfied by newNetwork, and reassigns to newNetwork 4757 // any such requests for which newNetwork is the best. 4758 // 4759 // - Lingers any validated Networks that as a result are no longer 4760 // needed. A network is needed if it is the best network for 4761 // one or more NetworkRequests, or if it is a VPN. 4762 // 4763 // - Tears down newNetwork if it just became validated 4764 // but turns out to be unneeded. 4765 // 4766 // - If reapUnvalidatedNetworks==REAP, tears down unvalidated 4767 // networks that have no chance (i.e. even if validated) 4768 // of becoming the highest scoring network. 4769 // 4770 // NOTE: This function only adds NetworkRequests that "newNetwork" could satisfy, 4771 // it does not remove NetworkRequests that other Networks could better satisfy. 4772 // If you need to handle decreases in score, use {@link rematchAllNetworksAndRequests}. 4773 // This function should be used when possible instead of {@code rematchAllNetworksAndRequests} 4774 // as it performs better by a factor of the number of Networks. 4775 // 4776 // @param newNetwork is the network to be matched against NetworkRequests. 4777 // @param reapUnvalidatedNetworks indicates if an additional pass over all networks should be 4778 // performed to tear down unvalidated networks that have no chance (i.e. even if 4779 // validated) of becoming the highest scoring network. rematchNetworkAndRequests(NetworkAgentInfo newNetwork, ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now)4780 private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, 4781 ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) { 4782 if (!newNetwork.everConnected) return; 4783 boolean keep = newNetwork.isVPN(); 4784 boolean isNewDefault = false; 4785 NetworkAgentInfo oldDefaultNetwork = null; 4786 if (VDBG) log("rematching " + newNetwork.name()); 4787 // Find and migrate to this Network any NetworkRequests for 4788 // which this network is now the best. 4789 ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>(); 4790 ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<NetworkRequestInfo>(); 4791 if (VDBG) log(" network has: " + newNetwork.networkCapabilities); 4792 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 4793 final NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId); 4794 final boolean satisfies = newNetwork.satisfies(nri.request); 4795 if (newNetwork == currentNetwork && satisfies) { 4796 if (VDBG) { 4797 log("Network " + newNetwork.name() + " was already satisfying" + 4798 " request " + nri.request.requestId + ". No change."); 4799 } 4800 keep = true; 4801 continue; 4802 } 4803 4804 // check if it satisfies the NetworkCapabilities 4805 if (VDBG) log(" checking if request is satisfied: " + nri.request); 4806 if (satisfies) { 4807 if (nri.request.isListen()) { 4808 // This is not a request, it's a callback listener. 4809 // Add it to newNetwork regardless of score. 4810 if (newNetwork.addRequest(nri.request)) addedRequests.add(nri); 4811 continue; 4812 } 4813 4814 // next check if it's better than any current network we're using for 4815 // this request 4816 if (VDBG) { 4817 log("currentScore = " + 4818 (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) + 4819 ", newScore = " + newNetwork.getCurrentScore()); 4820 } 4821 if (currentNetwork == null || 4822 currentNetwork.getCurrentScore() < newNetwork.getCurrentScore()) { 4823 if (VDBG) log("rematch for " + newNetwork.name()); 4824 if (currentNetwork != null) { 4825 if (VDBG) log(" accepting network in place of " + currentNetwork.name()); 4826 currentNetwork.removeRequest(nri.request.requestId); 4827 currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs); 4828 affectedNetworks.add(currentNetwork); 4829 } else { 4830 if (VDBG) log(" accepting network in place of null"); 4831 } 4832 newNetwork.unlingerRequest(nri.request); 4833 mNetworkForRequestId.put(nri.request.requestId, newNetwork); 4834 if (!newNetwork.addRequest(nri.request)) { 4835 Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request); 4836 } 4837 addedRequests.add(nri); 4838 keep = true; 4839 // Tell NetworkFactories about the new score, so they can stop 4840 // trying to connect if they know they cannot match it. 4841 // TODO - this could get expensive if we have alot of requests for this 4842 // network. Think about if there is a way to reduce this. Push 4843 // netid->request mapping to each factory? 4844 sendUpdatedScoreToFactories(nri.request, newNetwork.getCurrentScore()); 4845 if (isDefaultRequest(nri)) { 4846 isNewDefault = true; 4847 oldDefaultNetwork = currentNetwork; 4848 if (currentNetwork != null) { 4849 mLingerMonitor.noteLingerDefaultNetwork(currentNetwork, newNetwork); 4850 } 4851 } 4852 } 4853 } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) { 4854 // If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri", 4855 // mark it as no longer satisfying "nri". Because networks are processed by 4856 // rematchAllNetworksAndRequests() in descending score order, "currentNetwork" will 4857 // match "newNetwork" before this loop will encounter a "currentNetwork" with higher 4858 // score than "newNetwork" and where "currentNetwork" no longer satisfies "nri". 4859 // This means this code doesn't have to handle the case where "currentNetwork" no 4860 // longer satisfies "nri" when "currentNetwork" does not equal "newNetwork". 4861 if (DBG) { 4862 log("Network " + newNetwork.name() + " stopped satisfying" + 4863 " request " + nri.request.requestId); 4864 } 4865 newNetwork.removeRequest(nri.request.requestId); 4866 if (currentNetwork == newNetwork) { 4867 mNetworkForRequestId.remove(nri.request.requestId); 4868 sendUpdatedScoreToFactories(nri.request, 0); 4869 } else { 4870 if (nri.request.isRequest()) { 4871 Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " + 4872 newNetwork.name() + 4873 " without updating mNetworkForRequestId or factories!"); 4874 } 4875 } 4876 // TODO: technically, sending CALLBACK_LOST here is 4877 // incorrect if nri is a request (not a listen) and there 4878 // is a replacement network currently connected that can 4879 // satisfy it. However, the only capability that can both 4880 // a) be requested and b) change is NET_CAPABILITY_TRUSTED, 4881 // so this code is only incorrect for a network that loses 4882 // the TRUSTED capability, which is a rare case. 4883 callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0); 4884 } 4885 } 4886 if (isNewDefault) { 4887 // Notify system services that this network is up. 4888 makeDefault(newNetwork); 4889 // Log 0 -> X and Y -> X default network transitions, where X is the new default. 4890 logDefaultNetworkEvent(newNetwork, oldDefaultNetwork); 4891 synchronized (ConnectivityService.this) { 4892 // have a new default network, release the transition wakelock in 4893 // a second if it's held. The second pause is to allow apps 4894 // to reconnect over the new network 4895 if (mNetTransitionWakeLock.isHeld()) { 4896 mHandler.sendMessageDelayed(mHandler.obtainMessage( 4897 EVENT_CLEAR_NET_TRANSITION_WAKELOCK, 4898 mNetTransitionWakeLockSerialNumber, 0), 4899 1000); 4900 } 4901 } 4902 } 4903 4904 // do this after the default net is switched, but 4905 // before LegacyTypeTracker sends legacy broadcasts 4906 for (NetworkRequestInfo nri : addedRequests) notifyNetworkCallback(newNetwork, nri); 4907 4908 // Linger any networks that are no longer needed. This should be done after sending the 4909 // available callback for newNetwork. 4910 for (NetworkAgentInfo nai : affectedNetworks) { 4911 updateLingerState(nai, now); 4912 } 4913 // Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it 4914 // does not need to be done in any particular order. 4915 updateLingerState(newNetwork, now); 4916 4917 if (isNewDefault) { 4918 // Maintain the illusion: since the legacy API only 4919 // understands one network at a time, we must pretend 4920 // that the current default network disconnected before 4921 // the new one connected. 4922 if (oldDefaultNetwork != null) { 4923 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), 4924 oldDefaultNetwork, true); 4925 } 4926 mDefaultInetConditionPublished = newNetwork.lastValidated ? 100 : 0; 4927 mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork); 4928 notifyLockdownVpn(newNetwork); 4929 } 4930 4931 if (keep) { 4932 // Notify battery stats service about this network, both the normal 4933 // interface and any stacked links. 4934 // TODO: Avoid redoing this; this must only be done once when a network comes online. 4935 try { 4936 final IBatteryStats bs = BatteryStatsService.getService(); 4937 final int type = newNetwork.networkInfo.getType(); 4938 4939 final String baseIface = newNetwork.linkProperties.getInterfaceName(); 4940 bs.noteNetworkInterfaceType(baseIface, type); 4941 for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) { 4942 final String stackedIface = stacked.getInterfaceName(); 4943 bs.noteNetworkInterfaceType(stackedIface, type); 4944 NetworkStatsFactory.noteStackedIface(stackedIface, baseIface); 4945 } 4946 } catch (RemoteException ignored) { 4947 } 4948 4949 // This has to happen after the notifyNetworkCallbacks as that tickles each 4950 // ConnectivityManager instance so that legacy requests correctly bind dns 4951 // requests to this network. The legacy users are listening for this bcast 4952 // and will generally do a dns request so they can ensureRouteToHost and if 4953 // they do that before the callbacks happen they'll use the default network. 4954 // 4955 // TODO: Is there still a race here? We send the broadcast 4956 // after sending the callback, but if the app can receive the 4957 // broadcast before the callback, it might still break. 4958 // 4959 // This *does* introduce a race where if the user uses the new api 4960 // (notification callbacks) and then uses the old api (getNetworkInfo(type)) 4961 // they may get old info. Reverse this after the old startUsing api is removed. 4962 // This is on top of the multiple intent sequencing referenced in the todo above. 4963 for (int i = 0; i < newNetwork.numNetworkRequests(); i++) { 4964 NetworkRequest nr = newNetwork.requestAt(i); 4965 if (nr.legacyType != TYPE_NONE && nr.isRequest()) { 4966 // legacy type tracker filters out repeat adds 4967 mLegacyTypeTracker.add(nr.legacyType, newNetwork); 4968 } 4969 } 4970 4971 // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above, 4972 // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest 4973 // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the 4974 // newNetwork to the tracker explicitly (it's a no-op if it has already been added). 4975 if (newNetwork.isVPN()) { 4976 mLegacyTypeTracker.add(TYPE_VPN, newNetwork); 4977 } 4978 } 4979 if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) { 4980 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 4981 if (unneeded(nai)) { 4982 if (nai.getLingerExpiry() > 0) { 4983 // This network has active linger timers and no requests, but is not 4984 // lingering. Linger it. 4985 // 4986 // One way (the only way?) this can happen if this network is unvalidated 4987 // and became unneeded due to another network improving its score to the 4988 // point where this network will no longer be able to satisfy any requests 4989 // even if it validates. 4990 updateLingerState(nai, now); 4991 } else { 4992 if (DBG) log("Reaping " + nai.name()); 4993 teardownUnneededNetwork(nai); 4994 } 4995 } 4996 } 4997 } 4998 } 4999 5000 /** 5001 * Attempt to rematch all Networks with NetworkRequests. This may result in Networks 5002 * being disconnected. 5003 * @param changed If only one Network's score or capabilities have been modified since the last 5004 * time this function was called, pass this Network in this argument, otherwise pass 5005 * null. 5006 * @param oldScore If only one Network has been changed but its NetworkCapabilities have not 5007 * changed, pass in the Network's score (from getCurrentScore()) prior to the change via 5008 * this argument, otherwise pass {@code changed.getCurrentScore()} or 0 if 5009 * {@code changed} is {@code null}. This is because NetworkCapabilities influence a 5010 * network's score. 5011 */ rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore)5012 private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) { 5013 // TODO: This may get slow. The "changed" parameter is provided for future optimization 5014 // to avoid the slowness. It is not simply enough to process just "changed", for 5015 // example in the case where "changed"'s score decreases and another network should begin 5016 // satifying a NetworkRequest that "changed" currently satisfies. 5017 5018 // Optimization: Only reprocess "changed" if its score improved. This is safe because it 5019 // can only add more NetworkRequests satisfied by "changed", and this is exactly what 5020 // rematchNetworkAndRequests() handles. 5021 final long now = SystemClock.elapsedRealtime(); 5022 if (changed != null && oldScore < changed.getCurrentScore()) { 5023 rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now); 5024 } else { 5025 final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray( 5026 new NetworkAgentInfo[mNetworkAgentInfos.size()]); 5027 // Rematch higher scoring networks first to prevent requests first matching a lower 5028 // scoring network and then a higher scoring network, which could produce multiple 5029 // callbacks and inadvertently unlinger networks. 5030 Arrays.sort(nais); 5031 for (NetworkAgentInfo nai : nais) { 5032 rematchNetworkAndRequests(nai, 5033 // Only reap the last time through the loop. Reaping before all rematching 5034 // is complete could incorrectly teardown a network that hasn't yet been 5035 // rematched. 5036 (nai != nais[nais.length-1]) ? ReapUnvalidatedNetworks.DONT_REAP 5037 : ReapUnvalidatedNetworks.REAP, 5038 now); 5039 } 5040 } 5041 } 5042 updateInetCondition(NetworkAgentInfo nai)5043 private void updateInetCondition(NetworkAgentInfo nai) { 5044 // Don't bother updating until we've graduated to validated at least once. 5045 if (!nai.everValidated) return; 5046 // For now only update icons for default connection. 5047 // TODO: Update WiFi and cellular icons separately. b/17237507 5048 if (!isDefaultNetwork(nai)) return; 5049 5050 int newInetCondition = nai.lastValidated ? 100 : 0; 5051 // Don't repeat publish. 5052 if (newInetCondition == mDefaultInetConditionPublished) return; 5053 5054 mDefaultInetConditionPublished = newInetCondition; 5055 sendInetConditionBroadcast(nai.networkInfo); 5056 } 5057 notifyLockdownVpn(NetworkAgentInfo nai)5058 private void notifyLockdownVpn(NetworkAgentInfo nai) { 5059 if (mLockdownTracker != null) { 5060 if (nai != null && nai.isVPN()) { 5061 mLockdownTracker.onVpnStateChanged(nai.networkInfo); 5062 } else { 5063 mLockdownTracker.onNetworkInfoChanged(); 5064 } 5065 } 5066 } 5067 updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo)5068 private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) { 5069 NetworkInfo.State state = newInfo.getState(); 5070 NetworkInfo oldInfo = null; 5071 final int oldScore = networkAgent.getCurrentScore(); 5072 synchronized (networkAgent) { 5073 oldInfo = networkAgent.networkInfo; 5074 networkAgent.networkInfo = newInfo; 5075 } 5076 notifyLockdownVpn(networkAgent); 5077 5078 if (oldInfo != null && oldInfo.getState() == state) { 5079 if (oldInfo.isRoaming() != newInfo.isRoaming()) { 5080 if (VDBG) log("roaming status changed, notifying NetworkStatsService"); 5081 notifyIfacesChangedForNetworkStats(); 5082 } else if (VDBG) log("ignoring duplicate network state non-change"); 5083 // In either case, no further work should be needed. 5084 return; 5085 } 5086 if (DBG) { 5087 log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " + 5088 (oldInfo == null ? "null" : oldInfo.getState()) + 5089 " to " + state); 5090 } 5091 5092 if (!networkAgent.created 5093 && (state == NetworkInfo.State.CONNECTED 5094 || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) { 5095 try { 5096 // This should never fail. Specifying an already in use NetID will cause failure. 5097 if (networkAgent.isVPN()) { 5098 mNetd.createVirtualNetwork(networkAgent.network.netId, 5099 !networkAgent.linkProperties.getDnsServers().isEmpty(), 5100 (networkAgent.networkMisc == null || 5101 !networkAgent.networkMisc.allowBypass)); 5102 } else { 5103 mNetd.createPhysicalNetwork(networkAgent.network.netId, 5104 networkAgent.networkCapabilities.hasCapability( 5105 NET_CAPABILITY_NOT_RESTRICTED) ? 5106 null : NetworkManagementService.PERMISSION_SYSTEM); 5107 } 5108 } catch (Exception e) { 5109 loge("Error creating network " + networkAgent.network.netId + ": " 5110 + e.getMessage()); 5111 return; 5112 } 5113 networkAgent.created = true; 5114 } 5115 5116 if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) { 5117 networkAgent.everConnected = true; 5118 5119 updateLinkProperties(networkAgent, null); 5120 notifyIfacesChangedForNetworkStats(); 5121 5122 networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED); 5123 scheduleUnvalidatedPrompt(networkAgent); 5124 5125 if (networkAgent.isVPN()) { 5126 // Temporarily disable the default proxy (not global). 5127 synchronized (mProxyLock) { 5128 if (!mDefaultProxyDisabled) { 5129 mDefaultProxyDisabled = true; 5130 if (mGlobalProxy == null && mDefaultProxy != null) { 5131 sendProxyBroadcast(null); 5132 } 5133 } 5134 } 5135 // TODO: support proxy per network. 5136 } 5137 5138 // Whether a particular NetworkRequest listen should cause signal strength thresholds to 5139 // be communicated to a particular NetworkAgent depends only on the network's immutable, 5140 // capabilities, so it only needs to be done once on initial connect, not every time the 5141 // network's capabilities change. Note that we do this before rematching the network, 5142 // so we could decide to tear it down immediately afterwards. That's fine though - on 5143 // disconnection NetworkAgents should stop any signal strength monitoring they have been 5144 // doing. 5145 updateSignalStrengthThresholds(networkAgent, "CONNECT", null); 5146 5147 // Consider network even though it is not yet validated. 5148 final long now = SystemClock.elapsedRealtime(); 5149 rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP, now); 5150 5151 // This has to happen after matching the requests, because callbacks are just requests. 5152 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK); 5153 } else if (state == NetworkInfo.State.DISCONNECTED) { 5154 networkAgent.asyncChannel.disconnect(); 5155 if (networkAgent.isVPN()) { 5156 synchronized (mProxyLock) { 5157 if (mDefaultProxyDisabled) { 5158 mDefaultProxyDisabled = false; 5159 if (mGlobalProxy == null && mDefaultProxy != null) { 5160 sendProxyBroadcast(mDefaultProxy); 5161 } 5162 } 5163 } 5164 } 5165 } else if ((oldInfo != null && oldInfo.getState() == NetworkInfo.State.SUSPENDED) || 5166 state == NetworkInfo.State.SUSPENDED) { 5167 // going into or coming out of SUSPEND: rescore and notify 5168 if (networkAgent.getCurrentScore() != oldScore) { 5169 rematchAllNetworksAndRequests(networkAgent, oldScore); 5170 } 5171 notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ? 5172 ConnectivityManager.CALLBACK_SUSPENDED : 5173 ConnectivityManager.CALLBACK_RESUMED)); 5174 mLegacyTypeTracker.update(networkAgent); 5175 } 5176 } 5177 updateNetworkScore(NetworkAgentInfo nai, int score)5178 private void updateNetworkScore(NetworkAgentInfo nai, int score) { 5179 if (VDBG) log("updateNetworkScore for " + nai.name() + " to " + score); 5180 if (score < 0) { 5181 loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score + 5182 "). Bumping score to min of 0"); 5183 score = 0; 5184 } 5185 5186 final int oldScore = nai.getCurrentScore(); 5187 nai.setCurrentScore(score); 5188 5189 rematchAllNetworksAndRequests(nai, oldScore); 5190 5191 sendUpdatedScoreToFactories(nai); 5192 } 5193 5194 // notify only this one new request of the current state notifyNetworkCallback(NetworkAgentInfo nai, NetworkRequestInfo nri)5195 protected void notifyNetworkCallback(NetworkAgentInfo nai, NetworkRequestInfo nri) { 5196 int notifyType = ConnectivityManager.CALLBACK_AVAILABLE; 5197 if (nri.mPendingIntent == null) { 5198 callCallbackForRequest(nri, nai, notifyType, 0); 5199 } else { 5200 sendPendingIntentForRequest(nri, nai, notifyType); 5201 } 5202 } 5203 sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type)5204 private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) { 5205 // The NetworkInfo we actually send out has no bearing on the real 5206 // state of affairs. For example, if the default connection is mobile, 5207 // and a request for HIPRI has just gone away, we need to pretend that 5208 // HIPRI has just disconnected. So we need to set the type to HIPRI and 5209 // the state to DISCONNECTED, even though the network is of type MOBILE 5210 // and is still connected. 5211 NetworkInfo info = new NetworkInfo(nai.networkInfo); 5212 info.setType(type); 5213 if (state != DetailedState.DISCONNECTED) { 5214 info.setDetailedState(state, null, info.getExtraInfo()); 5215 sendConnectedBroadcast(info); 5216 } else { 5217 info.setDetailedState(state, info.getReason(), info.getExtraInfo()); 5218 Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 5219 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 5220 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 5221 if (info.isFailover()) { 5222 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 5223 nai.networkInfo.setFailover(false); 5224 } 5225 if (info.getReason() != null) { 5226 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 5227 } 5228 if (info.getExtraInfo() != null) { 5229 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo()); 5230 } 5231 NetworkAgentInfo newDefaultAgent = null; 5232 if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) { 5233 newDefaultAgent = getDefaultNetwork(); 5234 if (newDefaultAgent != null) { 5235 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, 5236 newDefaultAgent.networkInfo); 5237 } else { 5238 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); 5239 } 5240 } 5241 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, 5242 mDefaultInetConditionPublished); 5243 sendStickyBroadcast(intent); 5244 if (newDefaultAgent != null) { 5245 sendConnectedBroadcast(newDefaultAgent.networkInfo); 5246 } 5247 } 5248 } 5249 notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1)5250 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) { 5251 if (VDBG) log("notifyType " + notifyTypeToName(notifyType) + " for " + networkAgent.name()); 5252 for (int i = 0; i < networkAgent.numNetworkRequests(); i++) { 5253 NetworkRequest nr = networkAgent.requestAt(i); 5254 NetworkRequestInfo nri = mNetworkRequests.get(nr); 5255 if (VDBG) log(" sending notification for " + nr); 5256 if (nri.mPendingIntent == null) { 5257 callCallbackForRequest(nri, networkAgent, notifyType, arg1); 5258 } else { 5259 sendPendingIntentForRequest(nri, networkAgent, notifyType); 5260 } 5261 } 5262 } 5263 notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType)5264 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) { 5265 notifyNetworkCallbacks(networkAgent, notifyType, 0); 5266 } 5267 notifyTypeToName(int notifyType)5268 private String notifyTypeToName(int notifyType) { 5269 switch (notifyType) { 5270 case ConnectivityManager.CALLBACK_PRECHECK: return "PRECHECK"; 5271 case ConnectivityManager.CALLBACK_AVAILABLE: return "AVAILABLE"; 5272 case ConnectivityManager.CALLBACK_LOSING: return "LOSING"; 5273 case ConnectivityManager.CALLBACK_LOST: return "LOST"; 5274 case ConnectivityManager.CALLBACK_UNAVAIL: return "UNAVAILABLE"; 5275 case ConnectivityManager.CALLBACK_CAP_CHANGED: return "CAP_CHANGED"; 5276 case ConnectivityManager.CALLBACK_IP_CHANGED: return "IP_CHANGED"; 5277 case ConnectivityManager.CALLBACK_RELEASED: return "RELEASED"; 5278 } 5279 return "UNKNOWN"; 5280 } 5281 5282 /** 5283 * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the 5284 * properties tracked by NetworkStatsService on an active iface has changed. 5285 */ notifyIfacesChangedForNetworkStats()5286 private void notifyIfacesChangedForNetworkStats() { 5287 try { 5288 mStatsService.forceUpdateIfaces(); 5289 } catch (Exception ignored) { 5290 } 5291 } 5292 5293 @Override addVpnAddress(String address, int prefixLength)5294 public boolean addVpnAddress(String address, int prefixLength) { 5295 throwIfLockdownEnabled(); 5296 int user = UserHandle.getUserId(Binder.getCallingUid()); 5297 synchronized (mVpns) { 5298 return mVpns.get(user).addAddress(address, prefixLength); 5299 } 5300 } 5301 5302 @Override removeVpnAddress(String address, int prefixLength)5303 public boolean removeVpnAddress(String address, int prefixLength) { 5304 throwIfLockdownEnabled(); 5305 int user = UserHandle.getUserId(Binder.getCallingUid()); 5306 synchronized (mVpns) { 5307 return mVpns.get(user).removeAddress(address, prefixLength); 5308 } 5309 } 5310 5311 @Override setUnderlyingNetworksForVpn(Network[] networks)5312 public boolean setUnderlyingNetworksForVpn(Network[] networks) { 5313 throwIfLockdownEnabled(); 5314 int user = UserHandle.getUserId(Binder.getCallingUid()); 5315 boolean success; 5316 synchronized (mVpns) { 5317 success = mVpns.get(user).setUnderlyingNetworks(networks); 5318 } 5319 if (success) { 5320 notifyIfacesChangedForNetworkStats(); 5321 } 5322 return success; 5323 } 5324 5325 @Override getCaptivePortalServerUrl()5326 public String getCaptivePortalServerUrl() { 5327 return NetworkMonitor.getCaptivePortalServerUrl(mContext); 5328 } 5329 5330 @Override startNattKeepalive(Network network, int intervalSeconds, Messenger messenger, IBinder binder, String srcAddr, int srcPort, String dstAddr)5331 public void startNattKeepalive(Network network, int intervalSeconds, Messenger messenger, 5332 IBinder binder, String srcAddr, int srcPort, String dstAddr) { 5333 enforceKeepalivePermission(); 5334 mKeepaliveTracker.startNattKeepalive( 5335 getNetworkAgentInfoForNetwork(network), 5336 intervalSeconds, messenger, binder, 5337 srcAddr, srcPort, dstAddr, ConnectivityManager.PacketKeepalive.NATT_PORT); 5338 } 5339 5340 @Override stopKeepalive(Network network, int slot)5341 public void stopKeepalive(Network network, int slot) { 5342 mHandler.sendMessage(mHandler.obtainMessage( 5343 NetworkAgent.CMD_STOP_PACKET_KEEPALIVE, slot, PacketKeepalive.SUCCESS, network)); 5344 } 5345 5346 @Override factoryReset()5347 public void factoryReset() { 5348 enforceConnectivityInternalPermission(); 5349 5350 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 5351 return; 5352 } 5353 5354 final int userId = UserHandle.getCallingUserId(); 5355 5356 // Turn airplane mode off 5357 setAirplaneMode(false); 5358 5359 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) { 5360 // Untether 5361 for (String tether : getTetheredIfaces()) { 5362 untether(tether); 5363 } 5364 } 5365 5366 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) { 5367 // Remove always-on package 5368 synchronized (mVpns) { 5369 final String alwaysOnPackage = getAlwaysOnVpnPackage(userId); 5370 if (alwaysOnPackage != null) { 5371 setAlwaysOnVpnPackage(userId, null, false); 5372 setVpnPackageAuthorization(alwaysOnPackage, userId, false); 5373 } 5374 } 5375 5376 // Turn VPN off 5377 VpnConfig vpnConfig = getVpnConfig(userId); 5378 if (vpnConfig != null) { 5379 if (vpnConfig.legacy) { 5380 prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId); 5381 } else { 5382 // Prevent this app (packagename = vpnConfig.user) from initiating VPN connections 5383 // in the future without user intervention. 5384 setVpnPackageAuthorization(vpnConfig.user, userId, false); 5385 5386 prepareVpn(null, VpnConfig.LEGACY_VPN, userId); 5387 } 5388 } 5389 } 5390 5391 Settings.Global.putString(mContext.getContentResolver(), 5392 Settings.Global.NETWORK_AVOID_BAD_WIFI, null); 5393 } 5394 5395 @VisibleForTesting createNetworkMonitor(Context context, Handler handler, NetworkAgentInfo nai, NetworkRequest defaultRequest)5396 public NetworkMonitor createNetworkMonitor(Context context, Handler handler, 5397 NetworkAgentInfo nai, NetworkRequest defaultRequest) { 5398 return new NetworkMonitor(context, handler, nai, defaultRequest); 5399 } 5400 5401 @VisibleForTesting createAvoidBadWifiTracker(Context c, Handler h, Runnable r)5402 AvoidBadWifiTracker createAvoidBadWifiTracker(Context c, Handler h, Runnable r) { 5403 return new AvoidBadWifiTracker(c, h, r); 5404 } 5405 5406 @VisibleForTesting makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj)5407 public WakeupMessage makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj) { 5408 return new WakeupMessage(c, h, s, cmd, 0, 0, obj); 5409 } 5410 logDefaultNetworkEvent(NetworkAgentInfo newNai, NetworkAgentInfo prevNai)5411 private void logDefaultNetworkEvent(NetworkAgentInfo newNai, NetworkAgentInfo prevNai) { 5412 int newNetid = NETID_UNSET; 5413 int prevNetid = NETID_UNSET; 5414 int[] transports = new int[0]; 5415 boolean hadIPv4 = false; 5416 boolean hadIPv6 = false; 5417 5418 if (newNai != null) { 5419 newNetid = newNai.network.netId; 5420 transports = newNai.networkCapabilities.getTransportTypes(); 5421 } 5422 if (prevNai != null) { 5423 prevNetid = prevNai.network.netId; 5424 final LinkProperties lp = prevNai.linkProperties; 5425 hadIPv4 = lp.hasIPv4Address() && lp.hasIPv4DefaultRoute(); 5426 hadIPv6 = lp.hasGlobalIPv6Address() && lp.hasIPv6DefaultRoute(); 5427 } 5428 5429 mMetricsLog.log(new DefaultNetworkEvent(newNetid, transports, prevNetid, hadIPv4, hadIPv6)); 5430 } 5431 logNetworkEvent(NetworkAgentInfo nai, int evtype)5432 private void logNetworkEvent(NetworkAgentInfo nai, int evtype) { 5433 mMetricsLog.log(new NetworkEvent(nai.network.netId, evtype)); 5434 } 5435 } 5436