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