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