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