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 networkRequiresValidation(NetworkAgentInfo nai)2342 private boolean networkRequiresValidation(NetworkAgentInfo nai) { 2343 return NetworkMonitor.isValidationRequired( 2344 mDefaultRequest.networkCapabilities, nai.networkCapabilities); 2345 } 2346 handlePrivateDnsSettingsChanged()2347 private void handlePrivateDnsSettingsChanged() { 2348 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); 2349 2350 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 2351 handlePerNetworkPrivateDnsConfig(nai, cfg); 2352 if (networkRequiresValidation(nai)) { 2353 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 2354 } 2355 } 2356 } 2357 handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg)2358 private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) { 2359 // Private DNS only ever applies to networks that might provide 2360 // Internet access and therefore also require validation. 2361 if (!networkRequiresValidation(nai)) return; 2362 2363 // Notify the NetworkMonitor thread in case it needs to cancel or 2364 // schedule DNS resolutions. If a DNS resolution is required the 2365 // result will be sent back to us. 2366 nai.networkMonitor.notifyPrivateDnsSettingsChanged(cfg); 2367 2368 // With Private DNS bypass support, we can proceed to update the 2369 // Private DNS config immediately, even if we're in strict mode 2370 // and have not yet resolved the provider name into a set of IPs. 2371 updatePrivateDns(nai, cfg); 2372 } 2373 updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg)2374 private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) { 2375 mDnsManager.updatePrivateDns(nai.network, newCfg); 2376 updateDnses(nai.linkProperties, null, nai.network.netId); 2377 } 2378 handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update)2379 private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) { 2380 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId); 2381 if (nai == null) { 2382 return; 2383 } 2384 mDnsManager.updatePrivateDnsValidation(update); 2385 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); 2386 } 2387 updateLingerState(NetworkAgentInfo nai, long now)2388 private void updateLingerState(NetworkAgentInfo nai, long now) { 2389 // 1. Update the linger timer. If it's changed, reschedule or cancel the alarm. 2390 // 2. If the network was lingering and there are now requests, unlinger it. 2391 // 3. If this network is unneeded (which implies it is not lingering), and there is at least 2392 // one lingered request, start lingering. 2393 nai.updateLingerTimer(); 2394 if (nai.isLingering() && nai.numForegroundNetworkRequests() > 0) { 2395 if (DBG) log("Unlingering " + nai.name()); 2396 nai.unlinger(); 2397 logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER); 2398 } else if (unneeded(nai, UnneededFor.LINGER) && nai.getLingerExpiry() > 0) { 2399 int lingerTime = (int) (nai.getLingerExpiry() - now); 2400 if (DBG) log("Lingering " + nai.name() + " for " + lingerTime + "ms"); 2401 nai.linger(); 2402 logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER); 2403 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime); 2404 } 2405 } 2406 handleAsyncChannelHalfConnect(Message msg)2407 private void handleAsyncChannelHalfConnect(Message msg) { 2408 AsyncChannel ac = (AsyncChannel) msg.obj; 2409 if (mNetworkFactoryInfos.containsKey(msg.replyTo)) { 2410 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 2411 if (VDBG) log("NetworkFactory connected"); 2412 // A network factory has connected. Send it all current NetworkRequests. 2413 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 2414 if (nri.request.isListen()) continue; 2415 NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId); 2416 ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, 2417 (nai != null ? nai.getCurrentScore() : 0), 0, nri.request); 2418 } 2419 } else { 2420 loge("Error connecting NetworkFactory"); 2421 mNetworkFactoryInfos.remove(msg.obj); 2422 } 2423 } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) { 2424 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 2425 if (VDBG) log("NetworkAgent connected"); 2426 // A network agent has requested a connection. Establish the connection. 2427 mNetworkAgentInfos.get(msg.replyTo).asyncChannel. 2428 sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 2429 } else { 2430 loge("Error connecting NetworkAgent"); 2431 NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo); 2432 if (nai != null) { 2433 final boolean wasDefault = isDefaultNetwork(nai); 2434 synchronized (mNetworkForNetId) { 2435 mNetworkForNetId.remove(nai.network.netId); 2436 mNetIdInUse.delete(nai.network.netId); 2437 } 2438 // Just in case. 2439 mLegacyTypeTracker.remove(nai, wasDefault); 2440 } 2441 } 2442 } 2443 } 2444 2445 // This is a no-op if it's called with a message designating a network that has 2446 // already been destroyed, because its reference will not be found in the relevant 2447 // maps. handleAsyncChannelDisconnected(Message msg)2448 private void handleAsyncChannelDisconnected(Message msg) { 2449 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); 2450 if (nai != null) { 2451 disconnectAndDestroyNetwork(nai); 2452 } else { 2453 NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo); 2454 if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name); 2455 } 2456 } 2457 2458 // Destroys a network, remove references to it from the internal state managed by 2459 // ConnectivityService, free its interfaces and clean up. 2460 // Must be called on the Handler thread. disconnectAndDestroyNetwork(NetworkAgentInfo nai)2461 private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) { 2462 if (DBG) { 2463 log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests()); 2464 } 2465 // A network agent has disconnected. 2466 // TODO - if we move the logic to the network agent (have them disconnect 2467 // because they lost all their requests or because their score isn't good) 2468 // then they would disconnect organically, report their new state and then 2469 // disconnect the channel. 2470 if (nai.networkInfo.isConnected()) { 2471 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, 2472 null, null); 2473 } 2474 final boolean wasDefault = isDefaultNetwork(nai); 2475 if (wasDefault) { 2476 mDefaultInetConditionPublished = 0; 2477 // Log default network disconnection before required book-keeping. 2478 // Let rematchAllNetworksAndRequests() below record a new default network event 2479 // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence 2480 // whose timestamps tell how long it takes to recover a default network. 2481 long now = SystemClock.elapsedRealtime(); 2482 metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai); 2483 } 2484 notifyIfacesChangedForNetworkStats(); 2485 // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied 2486 // by other networks that are already connected. Perhaps that can be done by 2487 // sending all CALLBACK_LOST messages (for requests, not listens) at the end 2488 // of rematchAllNetworksAndRequests 2489 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST); 2490 mKeepaliveTracker.handleStopAllKeepalives(nai, 2491 ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK); 2492 for (String iface : nai.linkProperties.getAllInterfaceNames()) { 2493 // Disable wakeup packet monitoring for each interface. 2494 wakeupModifyInterface(iface, nai.networkCapabilities, false); 2495 } 2496 nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED); 2497 mNetworkAgentInfos.remove(nai.messenger); 2498 nai.maybeStopClat(); 2499 synchronized (mNetworkForNetId) { 2500 // Remove the NetworkAgent, but don't mark the netId as 2501 // available until we've told netd to delete it below. 2502 mNetworkForNetId.remove(nai.network.netId); 2503 } 2504 // Remove all previously satisfied requests. 2505 for (int i = 0; i < nai.numNetworkRequests(); i++) { 2506 NetworkRequest request = nai.requestAt(i); 2507 NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId); 2508 if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) { 2509 clearNetworkForRequest(request.requestId); 2510 sendUpdatedScoreToFactories(request, 0); 2511 } 2512 } 2513 nai.clearLingerState(); 2514 if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) { 2515 removeDataActivityTracking(nai); 2516 notifyLockdownVpn(nai); 2517 ensureNetworkTransitionWakelock(nai.name()); 2518 } 2519 mLegacyTypeTracker.remove(nai, wasDefault); 2520 if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) { 2521 updateAllVpnsCapabilities(); 2522 } 2523 rematchAllNetworksAndRequests(null, 0); 2524 mLingerMonitor.noteDisconnect(nai); 2525 if (nai.created) { 2526 // Tell netd to clean up the configuration for this network 2527 // (routing rules, DNS, etc). 2528 // This may be slow as it requires a lot of netd shelling out to ip and 2529 // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it 2530 // after we've rematched networks with requests which should make a potential 2531 // fallback network the default or requested a new network from the 2532 // NetworkFactories, so network traffic isn't interrupted for an unnecessarily 2533 // long time. 2534 try { 2535 mNetd.removeNetwork(nai.network.netId); 2536 } catch (Exception e) { 2537 loge("Exception removing network: " + e); 2538 } 2539 mDnsManager.removeNetwork(nai.network); 2540 } 2541 synchronized (mNetworkForNetId) { 2542 mNetIdInUse.delete(nai.network.netId); 2543 } 2544 } 2545 2546 // If this method proves to be too slow then we can maintain a separate 2547 // pendingIntent => NetworkRequestInfo map. 2548 // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo. findExistingNetworkRequestInfo(PendingIntent pendingIntent)2549 private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) { 2550 Intent intent = pendingIntent.getIntent(); 2551 for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) { 2552 PendingIntent existingPendingIntent = entry.getValue().mPendingIntent; 2553 if (existingPendingIntent != null && 2554 existingPendingIntent.getIntent().filterEquals(intent)) { 2555 return entry.getValue(); 2556 } 2557 } 2558 return null; 2559 } 2560 handleRegisterNetworkRequestWithIntent(Message msg)2561 private void handleRegisterNetworkRequestWithIntent(Message msg) { 2562 final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj); 2563 2564 NetworkRequestInfo existingRequest = findExistingNetworkRequestInfo(nri.mPendingIntent); 2565 if (existingRequest != null) { // remove the existing request. 2566 if (DBG) log("Replacing " + existingRequest.request + " with " 2567 + nri.request + " because their intents matched."); 2568 handleReleaseNetworkRequest(existingRequest.request, getCallingUid()); 2569 } 2570 handleRegisterNetworkRequest(nri); 2571 } 2572 handleRegisterNetworkRequest(NetworkRequestInfo nri)2573 private void handleRegisterNetworkRequest(NetworkRequestInfo nri) { 2574 mNetworkRequests.put(nri.request, nri); 2575 mNetworkRequestInfoLogs.log("REGISTER " + nri); 2576 if (nri.request.isListen()) { 2577 for (NetworkAgentInfo network : mNetworkAgentInfos.values()) { 2578 if (nri.request.networkCapabilities.hasSignalStrength() && 2579 network.satisfiesImmutableCapabilitiesOf(nri.request)) { 2580 updateSignalStrengthThresholds(network, "REGISTER", nri.request); 2581 } 2582 } 2583 } 2584 rematchAllNetworksAndRequests(null, 0); 2585 if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) { 2586 sendUpdatedScoreToFactories(nri.request, 0); 2587 } 2588 } 2589 handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent, int callingUid)2590 private void handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent, 2591 int callingUid) { 2592 NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent); 2593 if (nri != null) { 2594 handleReleaseNetworkRequest(nri.request, callingUid); 2595 } 2596 } 2597 2598 // Determines whether the network is the best (or could become the best, if it validated), for 2599 // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends 2600 // on the value of reason: 2601 // 2602 // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason, 2603 // then it should be torn down. 2604 // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason, 2605 // then it should be lingered. unneeded(NetworkAgentInfo nai, UnneededFor reason)2606 private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) { 2607 final int numRequests; 2608 switch (reason) { 2609 case TEARDOWN: 2610 numRequests = nai.numRequestNetworkRequests(); 2611 break; 2612 case LINGER: 2613 numRequests = nai.numForegroundNetworkRequests(); 2614 break; 2615 default: 2616 Slog.wtf(TAG, "Invalid reason. Cannot happen."); 2617 return true; 2618 } 2619 2620 if (!nai.everConnected || nai.isVPN() || nai.isLingering() || numRequests > 0) { 2621 return false; 2622 } 2623 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 2624 if (reason == UnneededFor.LINGER && nri.request.isBackgroundRequest()) { 2625 // Background requests don't affect lingering. 2626 continue; 2627 } 2628 2629 // If this Network is already the highest scoring Network for a request, or if 2630 // there is hope for it to become one if it validated, then it is needed. 2631 if (nri.request.isRequest() && nai.satisfies(nri.request) && 2632 (nai.isSatisfyingRequest(nri.request.requestId) || 2633 // Note that this catches two important cases: 2634 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi 2635 // is currently satisfying the request. This is desirable when 2636 // cellular ends up validating but WiFi does not. 2637 // 2. Unvalidated WiFi will not be reaped when validated cellular 2638 // is currently satisfying the request. This is desirable when 2639 // WiFi ends up validating and out scoring cellular. 2640 getNetworkForRequest(nri.request.requestId).getCurrentScore() < 2641 nai.getCurrentScoreAsValidated())) { 2642 return false; 2643 } 2644 } 2645 return true; 2646 } 2647 getNriForAppRequest( NetworkRequest request, int callingUid, String requestedOperation)2648 private NetworkRequestInfo getNriForAppRequest( 2649 NetworkRequest request, int callingUid, String requestedOperation) { 2650 final NetworkRequestInfo nri = mNetworkRequests.get(request); 2651 2652 if (nri != null) { 2653 if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) { 2654 log(String.format("UID %d attempted to %s for unowned request %s", 2655 callingUid, requestedOperation, nri)); 2656 return null; 2657 } 2658 } 2659 2660 return nri; 2661 } 2662 handleTimedOutNetworkRequest(final NetworkRequestInfo nri)2663 private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) { 2664 if (mNetworkRequests.get(nri.request) == null) { 2665 return; 2666 } 2667 if (getNetworkForRequest(nri.request.requestId) != null) { 2668 return; 2669 } 2670 if (VDBG || (DBG && nri.request.isRequest())) { 2671 log("releasing " + nri.request + " (timeout)"); 2672 } 2673 handleRemoveNetworkRequest(nri); 2674 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0); 2675 } 2676 handleReleaseNetworkRequest(NetworkRequest request, int callingUid)2677 private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) { 2678 final NetworkRequestInfo nri = 2679 getNriForAppRequest(request, callingUid, "release NetworkRequest"); 2680 if (nri == null) { 2681 return; 2682 } 2683 if (VDBG || (DBG && nri.request.isRequest())) { 2684 log("releasing " + nri.request + " (release request)"); 2685 } 2686 handleRemoveNetworkRequest(nri); 2687 } 2688 handleRemoveNetworkRequest(final NetworkRequestInfo nri)2689 private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) { 2690 nri.unlinkDeathRecipient(); 2691 mNetworkRequests.remove(nri.request); 2692 2693 synchronized (mUidToNetworkRequestCount) { 2694 int requests = mUidToNetworkRequestCount.get(nri.mUid, 0); 2695 if (requests < 1) { 2696 Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " + 2697 nri.mUid); 2698 } else if (requests == 1) { 2699 mUidToNetworkRequestCount.removeAt( 2700 mUidToNetworkRequestCount.indexOfKey(nri.mUid)); 2701 } else { 2702 mUidToNetworkRequestCount.put(nri.mUid, requests - 1); 2703 } 2704 } 2705 2706 mNetworkRequestInfoLogs.log("RELEASE " + nri); 2707 if (nri.request.isRequest()) { 2708 boolean wasKept = false; 2709 NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId); 2710 if (nai != null) { 2711 boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); 2712 nai.removeRequest(nri.request.requestId); 2713 if (VDBG) { 2714 log(" Removing from current network " + nai.name() + 2715 ", leaving " + nai.numNetworkRequests() + " requests."); 2716 } 2717 // If there are still lingered requests on this network, don't tear it down, 2718 // but resume lingering instead. 2719 updateLingerState(nai, SystemClock.elapsedRealtime()); 2720 if (unneeded(nai, UnneededFor.TEARDOWN)) { 2721 if (DBG) log("no live requests for " + nai.name() + "; disconnecting"); 2722 teardownUnneededNetwork(nai); 2723 } else { 2724 wasKept = true; 2725 } 2726 clearNetworkForRequest(nri.request.requestId); 2727 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) { 2728 // Went from foreground to background. 2729 updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities); 2730 } 2731 } 2732 2733 // TODO: remove this code once we know that the Slog.wtf is never hit. 2734 // 2735 // Find all networks that are satisfying this request and remove the request 2736 // from their request lists. 2737 // TODO - it's my understanding that for a request there is only a single 2738 // network satisfying it, so this loop is wasteful 2739 for (NetworkAgentInfo otherNai : mNetworkAgentInfos.values()) { 2740 if (otherNai.isSatisfyingRequest(nri.request.requestId) && otherNai != nai) { 2741 Slog.wtf(TAG, "Request " + nri.request + " satisfied by " + 2742 otherNai.name() + ", but mNetworkAgentInfos says " + 2743 (nai != null ? nai.name() : "null")); 2744 } 2745 } 2746 2747 // Maintain the illusion. When this request arrived, we might have pretended 2748 // that a network connected to serve it, even though the network was already 2749 // connected. Now that this request has gone away, we might have to pretend 2750 // that the network disconnected. LegacyTypeTracker will generate that 2751 // phantom disconnect for this type. 2752 if (nri.request.legacyType != TYPE_NONE && nai != null) { 2753 boolean doRemove = true; 2754 if (wasKept) { 2755 // check if any of the remaining requests for this network are for the 2756 // same legacy type - if so, don't remove the nai 2757 for (int i = 0; i < nai.numNetworkRequests(); i++) { 2758 NetworkRequest otherRequest = nai.requestAt(i); 2759 if (otherRequest.legacyType == nri.request.legacyType && 2760 otherRequest.isRequest()) { 2761 if (DBG) log(" still have other legacy request - leaving"); 2762 doRemove = false; 2763 } 2764 } 2765 } 2766 2767 if (doRemove) { 2768 mLegacyTypeTracker.remove(nri.request.legacyType, nai, false); 2769 } 2770 } 2771 2772 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { 2773 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, 2774 nri.request); 2775 } 2776 } else { 2777 // listens don't have a singular affectedNetwork. Check all networks to see 2778 // if this listen request applies and remove it. 2779 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 2780 nai.removeRequest(nri.request.requestId); 2781 if (nri.request.networkCapabilities.hasSignalStrength() && 2782 nai.satisfiesImmutableCapabilitiesOf(nri.request)) { 2783 updateSignalStrengthThresholds(nai, "RELEASE", nri.request); 2784 } 2785 } 2786 } 2787 } 2788 2789 @Override setAcceptUnvalidated(Network network, boolean accept, boolean always)2790 public void setAcceptUnvalidated(Network network, boolean accept, boolean always) { 2791 enforceConnectivityInternalPermission(); 2792 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED, 2793 encodeBool(accept), encodeBool(always), network)); 2794 } 2795 2796 @Override setAvoidUnvalidated(Network network)2797 public void setAvoidUnvalidated(Network network) { 2798 enforceConnectivityInternalPermission(); 2799 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network)); 2800 } 2801 handleSetAcceptUnvalidated(Network network, boolean accept, boolean always)2802 private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) { 2803 if (DBG) log("handleSetAcceptUnvalidated network=" + network + 2804 " accept=" + accept + " always=" + always); 2805 2806 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2807 if (nai == null) { 2808 // Nothing to do. 2809 return; 2810 } 2811 2812 if (nai.everValidated) { 2813 // The network validated while the dialog box was up. Take no action. 2814 return; 2815 } 2816 2817 if (!nai.networkMisc.explicitlySelected) { 2818 Slog.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network"); 2819 } 2820 2821 if (accept != nai.networkMisc.acceptUnvalidated) { 2822 int oldScore = nai.getCurrentScore(); 2823 nai.networkMisc.acceptUnvalidated = accept; 2824 rematchAllNetworksAndRequests(nai, oldScore); 2825 sendUpdatedScoreToFactories(nai); 2826 } 2827 2828 if (always) { 2829 nai.asyncChannel.sendMessage( 2830 NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept)); 2831 } 2832 2833 if (!accept) { 2834 // Tell the NetworkAgent to not automatically reconnect to the network. 2835 nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); 2836 // Teardown the nework. 2837 teardownUnneededNetwork(nai); 2838 } 2839 2840 } 2841 handleSetAvoidUnvalidated(Network network)2842 private void handleSetAvoidUnvalidated(Network network) { 2843 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2844 if (nai == null || nai.lastValidated) { 2845 // Nothing to do. The network either disconnected or revalidated. 2846 return; 2847 } 2848 if (!nai.avoidUnvalidated) { 2849 int oldScore = nai.getCurrentScore(); 2850 nai.avoidUnvalidated = true; 2851 rematchAllNetworksAndRequests(nai, oldScore); 2852 sendUpdatedScoreToFactories(nai); 2853 } 2854 } 2855 scheduleUnvalidatedPrompt(NetworkAgentInfo nai)2856 private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) { 2857 if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network); 2858 mHandler.sendMessageDelayed( 2859 mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network), 2860 PROMPT_UNVALIDATED_DELAY_MS); 2861 } 2862 2863 @Override startCaptivePortalApp(Network network)2864 public void startCaptivePortalApp(Network network) { 2865 enforceConnectivityInternalPermission(); 2866 mHandler.post(() -> { 2867 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2868 if (nai == null) return; 2869 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return; 2870 nai.networkMonitor.sendMessage(NetworkMonitor.CMD_LAUNCH_CAPTIVE_PORTAL_APP); 2871 }); 2872 } 2873 avoidBadWifi()2874 public boolean avoidBadWifi() { 2875 return mMultinetworkPolicyTracker.getAvoidBadWifi(); 2876 } 2877 rematchForAvoidBadWifiUpdate()2878 private void rematchForAvoidBadWifiUpdate() { 2879 rematchAllNetworksAndRequests(null, 0); 2880 for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) { 2881 if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 2882 sendUpdatedScoreToFactories(nai); 2883 } 2884 } 2885 } 2886 2887 // TODO: Evaluate whether this is of interest to other consumers of 2888 // MultinetworkPolicyTracker and worth moving out of here. dumpAvoidBadWifiSettings(IndentingPrintWriter pw)2889 private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) { 2890 final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi(); 2891 if (!configRestrict) { 2892 pw.println("Bad Wi-Fi avoidance: unrestricted"); 2893 return; 2894 } 2895 2896 pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi()); 2897 pw.increaseIndent(); 2898 pw.println("Config restrict: " + configRestrict); 2899 2900 final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting(); 2901 String description; 2902 // Can't use a switch statement because strings are legal case labels, but null is not. 2903 if ("0".equals(value)) { 2904 description = "get stuck"; 2905 } else if (value == null) { 2906 description = "prompt"; 2907 } else if ("1".equals(value)) { 2908 description = "avoid"; 2909 } else { 2910 description = value + " (?)"; 2911 } 2912 pw.println("User setting: " + description); 2913 pw.println("Network overrides:"); 2914 pw.increaseIndent(); 2915 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 2916 if (nai.avoidUnvalidated) { 2917 pw.println(nai.name()); 2918 } 2919 } 2920 pw.decreaseIndent(); 2921 pw.decreaseIndent(); 2922 } 2923 showValidationNotification(NetworkAgentInfo nai, NotificationType type)2924 private void showValidationNotification(NetworkAgentInfo nai, NotificationType type) { 2925 final String action; 2926 switch (type) { 2927 case NO_INTERNET: 2928 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED; 2929 break; 2930 case LOST_INTERNET: 2931 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION; 2932 break; 2933 default: 2934 Slog.wtf(TAG, "Unknown notification type " + type); 2935 return; 2936 } 2937 2938 Intent intent = new Intent(action); 2939 intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null)); 2940 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2941 intent.setClassName("com.android.settings", 2942 "com.android.settings.wifi.WifiNoInternetDialog"); 2943 2944 PendingIntent pendingIntent = PendingIntent.getActivityAsUser( 2945 mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 2946 mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, true); 2947 } 2948 handlePromptUnvalidated(Network network)2949 private void handlePromptUnvalidated(Network network) { 2950 if (VDBG) log("handlePromptUnvalidated " + network); 2951 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2952 2953 // Only prompt if the network is unvalidated and was explicitly selected by the user, and if 2954 // we haven't already been told to switch to it regardless of whether it validated or not. 2955 // Also don't prompt on captive portals because we're already prompting the user to sign in. 2956 if (nai == null || nai.everValidated || nai.everCaptivePortalDetected || 2957 !nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) { 2958 return; 2959 } 2960 showValidationNotification(nai, NotificationType.NO_INTERNET); 2961 } 2962 handleNetworkUnvalidated(NetworkAgentInfo nai)2963 private void handleNetworkUnvalidated(NetworkAgentInfo nai) { 2964 NetworkCapabilities nc = nai.networkCapabilities; 2965 if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc); 2966 2967 if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && 2968 mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) { 2969 showValidationNotification(nai, NotificationType.LOST_INTERNET); 2970 } 2971 } 2972 2973 @Override getMultipathPreference(Network network)2974 public int getMultipathPreference(Network network) { 2975 enforceAccessPermission(); 2976 2977 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 2978 if (nai != null && nai.networkCapabilities 2979 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) { 2980 return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED; 2981 } 2982 2983 Integer networkPreference = mMultipathPolicyTracker.getMultipathPreference(network); 2984 if (networkPreference != null) { 2985 return networkPreference; 2986 } 2987 2988 return mMultinetworkPolicyTracker.getMeteredMultipathPreference(); 2989 } 2990 2991 private class InternalHandler extends Handler { InternalHandler(Looper looper)2992 public InternalHandler(Looper looper) { 2993 super(looper); 2994 } 2995 2996 @Override handleMessage(Message msg)2997 public void handleMessage(Message msg) { 2998 switch (msg.what) { 2999 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK: 3000 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: { 3001 handleReleaseNetworkTransitionWakelock(msg.what); 3002 break; 3003 } 3004 case EVENT_APPLY_GLOBAL_HTTP_PROXY: { 3005 handleDeprecatedGlobalHttpProxy(); 3006 break; 3007 } 3008 case EVENT_PROXY_HAS_CHANGED: { 3009 handleApplyDefaultProxy((ProxyInfo)msg.obj); 3010 break; 3011 } 3012 case EVENT_REGISTER_NETWORK_FACTORY: { 3013 handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj); 3014 break; 3015 } 3016 case EVENT_UNREGISTER_NETWORK_FACTORY: { 3017 handleUnregisterNetworkFactory((Messenger)msg.obj); 3018 break; 3019 } 3020 case EVENT_REGISTER_NETWORK_AGENT: { 3021 handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj); 3022 break; 3023 } 3024 case EVENT_REGISTER_NETWORK_REQUEST: 3025 case EVENT_REGISTER_NETWORK_LISTENER: { 3026 handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj); 3027 break; 3028 } 3029 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: 3030 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: { 3031 handleRegisterNetworkRequestWithIntent(msg); 3032 break; 3033 } 3034 case EVENT_TIMEOUT_NETWORK_REQUEST: { 3035 NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj; 3036 handleTimedOutNetworkRequest(nri); 3037 break; 3038 } 3039 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: { 3040 handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1); 3041 break; 3042 } 3043 case EVENT_RELEASE_NETWORK_REQUEST: { 3044 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1); 3045 break; 3046 } 3047 case EVENT_SET_ACCEPT_UNVALIDATED: { 3048 Network network = (Network) msg.obj; 3049 handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2)); 3050 break; 3051 } 3052 case EVENT_SET_AVOID_UNVALIDATED: { 3053 handleSetAvoidUnvalidated((Network) msg.obj); 3054 break; 3055 } 3056 case EVENT_PROMPT_UNVALIDATED: { 3057 handlePromptUnvalidated((Network) msg.obj); 3058 break; 3059 } 3060 case EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON: { 3061 handleMobileDataAlwaysOn(); 3062 break; 3063 } 3064 // Sent by KeepaliveTracker to process an app request on the state machine thread. 3065 case NetworkAgent.CMD_START_PACKET_KEEPALIVE: { 3066 mKeepaliveTracker.handleStartKeepalive(msg); 3067 break; 3068 } 3069 // Sent by KeepaliveTracker to process an app request on the state machine thread. 3070 case NetworkAgent.CMD_STOP_PACKET_KEEPALIVE: { 3071 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj); 3072 int slot = msg.arg1; 3073 int reason = msg.arg2; 3074 mKeepaliveTracker.handleStopKeepalive(nai, slot, reason); 3075 break; 3076 } 3077 case EVENT_SYSTEM_READY: { 3078 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 3079 nai.networkMonitor.systemReady = true; 3080 } 3081 mMultipathPolicyTracker.start(); 3082 break; 3083 } 3084 case EVENT_REVALIDATE_NETWORK: { 3085 handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2)); 3086 break; 3087 } 3088 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED: 3089 handlePrivateDnsSettingsChanged(); 3090 break; 3091 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE: 3092 handlePrivateDnsValidationUpdate( 3093 (PrivateDnsValidationUpdate) msg.obj); 3094 break; 3095 } 3096 } 3097 } 3098 3099 // javadoc from interface 3100 @Override tether(String iface, String callerPkg)3101 public int tether(String iface, String callerPkg) { 3102 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3103 if (isTetheringSupported()) { 3104 final int status = mTethering.tether(iface); 3105 return status; 3106 } else { 3107 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3108 } 3109 } 3110 3111 // javadoc from interface 3112 @Override untether(String iface, String callerPkg)3113 public int untether(String iface, String callerPkg) { 3114 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3115 3116 if (isTetheringSupported()) { 3117 final int status = mTethering.untether(iface); 3118 return status; 3119 } else { 3120 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3121 } 3122 } 3123 3124 // javadoc from interface 3125 @Override getLastTetherError(String iface)3126 public int getLastTetherError(String iface) { 3127 enforceTetherAccessPermission(); 3128 3129 if (isTetheringSupported()) { 3130 return mTethering.getLastTetherError(iface); 3131 } else { 3132 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3133 } 3134 } 3135 3136 // TODO - proper iface API for selection by property, inspection, etc 3137 @Override getTetherableUsbRegexs()3138 public String[] getTetherableUsbRegexs() { 3139 enforceTetherAccessPermission(); 3140 if (isTetheringSupported()) { 3141 return mTethering.getTetherableUsbRegexs(); 3142 } else { 3143 return new String[0]; 3144 } 3145 } 3146 3147 @Override getTetherableWifiRegexs()3148 public String[] getTetherableWifiRegexs() { 3149 enforceTetherAccessPermission(); 3150 if (isTetheringSupported()) { 3151 return mTethering.getTetherableWifiRegexs(); 3152 } else { 3153 return new String[0]; 3154 } 3155 } 3156 3157 @Override getTetherableBluetoothRegexs()3158 public String[] getTetherableBluetoothRegexs() { 3159 enforceTetherAccessPermission(); 3160 if (isTetheringSupported()) { 3161 return mTethering.getTetherableBluetoothRegexs(); 3162 } else { 3163 return new String[0]; 3164 } 3165 } 3166 3167 @Override setUsbTethering(boolean enable, String callerPkg)3168 public int setUsbTethering(boolean enable, String callerPkg) { 3169 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3170 if (isTetheringSupported()) { 3171 return mTethering.setUsbTethering(enable); 3172 } else { 3173 return ConnectivityManager.TETHER_ERROR_UNSUPPORTED; 3174 } 3175 } 3176 3177 // TODO - move iface listing, queries, etc to new module 3178 // javadoc from interface 3179 @Override getTetherableIfaces()3180 public String[] getTetherableIfaces() { 3181 enforceTetherAccessPermission(); 3182 return mTethering.getTetherableIfaces(); 3183 } 3184 3185 @Override getTetheredIfaces()3186 public String[] getTetheredIfaces() { 3187 enforceTetherAccessPermission(); 3188 return mTethering.getTetheredIfaces(); 3189 } 3190 3191 @Override getTetheringErroredIfaces()3192 public String[] getTetheringErroredIfaces() { 3193 enforceTetherAccessPermission(); 3194 return mTethering.getErroredIfaces(); 3195 } 3196 3197 @Override getTetheredDhcpRanges()3198 public String[] getTetheredDhcpRanges() { 3199 enforceConnectivityInternalPermission(); 3200 return mTethering.getTetheredDhcpRanges(); 3201 } 3202 3203 @Override isTetheringSupported(String callerPkg)3204 public boolean isTetheringSupported(String callerPkg) { 3205 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3206 return isTetheringSupported(); 3207 } 3208 3209 // if ro.tether.denied = true we default to no tethering 3210 // gservices could set the secure setting to 1 though to enable it on a build where it 3211 // had previously been turned off. isTetheringSupported()3212 private boolean isTetheringSupported() { 3213 int defaultVal = encodeBool(!mSystemProperties.get("ro.tether.denied").equals("true")); 3214 boolean tetherSupported = toBool(Settings.Global.getInt(mContext.getContentResolver(), 3215 Settings.Global.TETHER_SUPPORTED, defaultVal)); 3216 boolean tetherEnabledInSettings = tetherSupported 3217 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING); 3218 3219 // Elevate to system UID to avoid caller requiring MANAGE_USERS permission. 3220 boolean adminUser = false; 3221 final long token = Binder.clearCallingIdentity(); 3222 try { 3223 adminUser = mUserManager.isAdminUser(); 3224 } finally { 3225 Binder.restoreCallingIdentity(token); 3226 } 3227 3228 return tetherEnabledInSettings && adminUser && mTethering.hasTetherableConfiguration(); 3229 } 3230 3231 @Override startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi, String callerPkg)3232 public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi, 3233 String callerPkg) { 3234 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3235 if (!isTetheringSupported()) { 3236 receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null); 3237 return; 3238 } 3239 mTethering.startTethering(type, receiver, showProvisioningUi); 3240 } 3241 3242 @Override stopTethering(int type, String callerPkg)3243 public void stopTethering(int type, String callerPkg) { 3244 ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); 3245 mTethering.stopTethering(type); 3246 } 3247 3248 // Called when we lose the default network and have no replacement yet. 3249 // This will automatically be cleared after X seconds or a new default network 3250 // becomes CONNECTED, whichever happens first. The timer is started by the 3251 // first caller and not restarted by subsequent callers. ensureNetworkTransitionWakelock(String forWhom)3252 private void ensureNetworkTransitionWakelock(String forWhom) { 3253 synchronized (this) { 3254 if (mNetTransitionWakeLock.isHeld()) { 3255 return; 3256 } 3257 mNetTransitionWakeLock.acquire(); 3258 mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime(); 3259 mTotalWakelockAcquisitions++; 3260 } 3261 mWakelockLogs.log("ACQUIRE for " + forWhom); 3262 Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 3263 mHandler.sendMessageDelayed(msg, mNetTransitionWakeLockTimeout); 3264 } 3265 3266 // Called when we gain a new default network to release the network transition wakelock in a 3267 // second, to allow a grace period for apps to reconnect over the new network. Pending expiry 3268 // message is cancelled. scheduleReleaseNetworkTransitionWakelock()3269 private void scheduleReleaseNetworkTransitionWakelock() { 3270 synchronized (this) { 3271 if (!mNetTransitionWakeLock.isHeld()) { 3272 return; // expiry message released the lock first. 3273 } 3274 } 3275 // Cancel self timeout on wakelock hold. 3276 mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK); 3277 Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK); 3278 mHandler.sendMessageDelayed(msg, 1000); 3279 } 3280 3281 // Called when either message of ensureNetworkTransitionWakelock or 3282 // scheduleReleaseNetworkTransitionWakelock is processed. handleReleaseNetworkTransitionWakelock(int eventId)3283 private void handleReleaseNetworkTransitionWakelock(int eventId) { 3284 String event = eventName(eventId); 3285 synchronized (this) { 3286 if (!mNetTransitionWakeLock.isHeld()) { 3287 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event)); 3288 Slog.w(TAG, "expected Net Transition WakeLock to be held"); 3289 return; 3290 } 3291 mNetTransitionWakeLock.release(); 3292 long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp; 3293 mTotalWakelockDurationMs += lockDuration; 3294 mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration); 3295 mTotalWakelockReleases++; 3296 } 3297 mWakelockLogs.log(String.format("RELEASE (%s)", event)); 3298 } 3299 3300 // 100 percent is full good, 0 is full bad. 3301 @Override reportInetCondition(int networkType, int percentage)3302 public void reportInetCondition(int networkType, int percentage) { 3303 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); 3304 if (nai == null) return; 3305 reportNetworkConnectivity(nai.network, percentage > 50); 3306 } 3307 3308 @Override reportNetworkConnectivity(Network network, boolean hasConnectivity)3309 public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { 3310 enforceAccessPermission(); 3311 enforceInternetPermission(); 3312 final int uid = Binder.getCallingUid(); 3313 final int connectivityInfo = encodeBool(hasConnectivity); 3314 mHandler.sendMessage( 3315 mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network)); 3316 } 3317 handleReportNetworkConnectivity( Network network, int uid, boolean hasConnectivity)3318 private void handleReportNetworkConnectivity( 3319 Network network, int uid, boolean hasConnectivity) { 3320 final NetworkAgentInfo nai; 3321 if (network == null) { 3322 nai = getDefaultNetwork(); 3323 } else { 3324 nai = getNetworkAgentInfoForNetwork(network); 3325 } 3326 if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING || 3327 nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) { 3328 return; 3329 } 3330 // Revalidate if the app report does not match our current validated state. 3331 if (hasConnectivity == nai.lastValidated) { 3332 return; 3333 } 3334 if (DBG) { 3335 int netid = nai.network.netId; 3336 log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid); 3337 } 3338 // Validating a network that has not yet connected could result in a call to 3339 // rematchNetworkAndRequests() which is not meant to work on such networks. 3340 if (!nai.everConnected) { 3341 return; 3342 } 3343 LinkProperties lp = getLinkProperties(nai); 3344 if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) { 3345 return; 3346 } 3347 nai.networkMonitor.forceReevaluation(uid); 3348 } 3349 getDefaultProxy()3350 private ProxyInfo getDefaultProxy() { 3351 // this information is already available as a world read/writable jvm property 3352 // so this API change wouldn't have a benifit. It also breaks the passing 3353 // of proxy info to all the JVMs. 3354 // enforceAccessPermission(); 3355 synchronized (mProxyLock) { 3356 ProxyInfo ret = mGlobalProxy; 3357 if ((ret == null) && !mDefaultProxyDisabled) ret = mDefaultProxy; 3358 return ret; 3359 } 3360 } 3361 3362 @Override getProxyForNetwork(Network network)3363 public ProxyInfo getProxyForNetwork(Network network) { 3364 if (network == null) return getDefaultProxy(); 3365 final ProxyInfo globalProxy = getGlobalProxy(); 3366 if (globalProxy != null) return globalProxy; 3367 if (!NetworkUtils.queryUserAccess(Binder.getCallingUid(), network.netId)) return null; 3368 // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which 3369 // caller may not have. 3370 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); 3371 if (nai == null) return null; 3372 synchronized (nai) { 3373 final ProxyInfo proxyInfo = nai.linkProperties.getHttpProxy(); 3374 if (proxyInfo == null) return null; 3375 return new ProxyInfo(proxyInfo); 3376 } 3377 } 3378 3379 // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present 3380 // (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific 3381 // proxy is null then there is no proxy in place). canonicalizeProxyInfo(ProxyInfo proxy)3382 private ProxyInfo canonicalizeProxyInfo(ProxyInfo proxy) { 3383 if (proxy != null && TextUtils.isEmpty(proxy.getHost()) 3384 && (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) { 3385 proxy = null; 3386 } 3387 return proxy; 3388 } 3389 3390 // ProxyInfo equality function with a couple modifications over ProxyInfo.equals() to make it 3391 // better for determining if a new proxy broadcast is necessary: 3392 // 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to 3393 // avoid unnecessary broadcasts. 3394 // 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL 3395 // is in place. This is important so legacy PAC resolver (see com.android.proxyhandler) 3396 // changes aren't missed. The legacy PAC resolver pretends to be a simple HTTP proxy but 3397 // actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port 3398 // all set. proxyInfoEqual(ProxyInfo a, ProxyInfo b)3399 private boolean proxyInfoEqual(ProxyInfo a, ProxyInfo b) { 3400 a = canonicalizeProxyInfo(a); 3401 b = canonicalizeProxyInfo(b); 3402 // ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check 3403 // hosts even when PAC URLs are present to account for the legacy PAC resolver. 3404 return Objects.equals(a, b) && (a == null || Objects.equals(a.getHost(), b.getHost())); 3405 } 3406 setGlobalProxy(ProxyInfo proxyProperties)3407 public void setGlobalProxy(ProxyInfo proxyProperties) { 3408 enforceConnectivityInternalPermission(); 3409 3410 synchronized (mProxyLock) { 3411 if (proxyProperties == mGlobalProxy) return; 3412 if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return; 3413 if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return; 3414 3415 String host = ""; 3416 int port = 0; 3417 String exclList = ""; 3418 String pacFileUrl = ""; 3419 if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) || 3420 !Uri.EMPTY.equals(proxyProperties.getPacFileUrl()))) { 3421 if (!proxyProperties.isValid()) { 3422 if (DBG) 3423 log("Invalid proxy properties, ignoring: " + proxyProperties.toString()); 3424 return; 3425 } 3426 mGlobalProxy = new ProxyInfo(proxyProperties); 3427 host = mGlobalProxy.getHost(); 3428 port = mGlobalProxy.getPort(); 3429 exclList = mGlobalProxy.getExclusionListAsString(); 3430 if (!Uri.EMPTY.equals(proxyProperties.getPacFileUrl())) { 3431 pacFileUrl = proxyProperties.getPacFileUrl().toString(); 3432 } 3433 } else { 3434 mGlobalProxy = null; 3435 } 3436 ContentResolver res = mContext.getContentResolver(); 3437 final long token = Binder.clearCallingIdentity(); 3438 try { 3439 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host); 3440 Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port); 3441 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST, 3442 exclList); 3443 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl); 3444 } finally { 3445 Binder.restoreCallingIdentity(token); 3446 } 3447 3448 if (mGlobalProxy == null) { 3449 proxyProperties = mDefaultProxy; 3450 } 3451 sendProxyBroadcast(proxyProperties); 3452 } 3453 } 3454 loadGlobalProxy()3455 private void loadGlobalProxy() { 3456 ContentResolver res = mContext.getContentResolver(); 3457 String host = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST); 3458 int port = Settings.Global.getInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, 0); 3459 String exclList = Settings.Global.getString(res, 3460 Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST); 3461 String pacFileUrl = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC); 3462 if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) { 3463 ProxyInfo proxyProperties; 3464 if (!TextUtils.isEmpty(pacFileUrl)) { 3465 proxyProperties = new ProxyInfo(pacFileUrl); 3466 } else { 3467 proxyProperties = new ProxyInfo(host, port, exclList); 3468 } 3469 if (!proxyProperties.isValid()) { 3470 if (DBG) log("Invalid proxy properties, ignoring: " + proxyProperties.toString()); 3471 return; 3472 } 3473 3474 synchronized (mProxyLock) { 3475 mGlobalProxy = proxyProperties; 3476 } 3477 } 3478 } 3479 getGlobalProxy()3480 public ProxyInfo getGlobalProxy() { 3481 // this information is already available as a world read/writable jvm property 3482 // so this API change wouldn't have a benifit. It also breaks the passing 3483 // of proxy info to all the JVMs. 3484 // enforceAccessPermission(); 3485 synchronized (mProxyLock) { 3486 return mGlobalProxy; 3487 } 3488 } 3489 handleApplyDefaultProxy(ProxyInfo proxy)3490 private void handleApplyDefaultProxy(ProxyInfo proxy) { 3491 if (proxy != null && TextUtils.isEmpty(proxy.getHost()) 3492 && Uri.EMPTY.equals(proxy.getPacFileUrl())) { 3493 proxy = null; 3494 } 3495 synchronized (mProxyLock) { 3496 if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return; 3497 if (mDefaultProxy == proxy) return; // catches repeated nulls 3498 if (proxy != null && !proxy.isValid()) { 3499 if (DBG) log("Invalid proxy properties, ignoring: " + proxy.toString()); 3500 return; 3501 } 3502 3503 // This call could be coming from the PacManager, containing the port of the local 3504 // proxy. If this new proxy matches the global proxy then copy this proxy to the 3505 // global (to get the correct local port), and send a broadcast. 3506 // TODO: Switch PacManager to have its own message to send back rather than 3507 // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy. 3508 if ((mGlobalProxy != null) && (proxy != null) 3509 && (!Uri.EMPTY.equals(proxy.getPacFileUrl())) 3510 && proxy.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) { 3511 mGlobalProxy = proxy; 3512 sendProxyBroadcast(mGlobalProxy); 3513 return; 3514 } 3515 mDefaultProxy = proxy; 3516 3517 if (mGlobalProxy != null) return; 3518 if (!mDefaultProxyDisabled) { 3519 sendProxyBroadcast(proxy); 3520 } 3521 } 3522 } 3523 3524 // If the proxy has changed from oldLp to newLp, resend proxy broadcast with default proxy. 3525 // This method gets called when any network changes proxy, but the broadcast only ever contains 3526 // the default proxy (even if it hasn't changed). 3527 // TODO: Deprecate the broadcast extras as they aren't necessarily applicable in a multi-network 3528 // world where an app might be bound to a non-default network. updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai)3529 private void updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) { 3530 ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy(); 3531 ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy(); 3532 3533 if (!proxyInfoEqual(newProxyInfo, oldProxyInfo)) { 3534 sendProxyBroadcast(getDefaultProxy()); 3535 } 3536 } 3537 handleDeprecatedGlobalHttpProxy()3538 private void handleDeprecatedGlobalHttpProxy() { 3539 String proxy = Settings.Global.getString(mContext.getContentResolver(), 3540 Settings.Global.HTTP_PROXY); 3541 if (!TextUtils.isEmpty(proxy)) { 3542 String data[] = proxy.split(":"); 3543 if (data.length == 0) { 3544 return; 3545 } 3546 3547 String proxyHost = data[0]; 3548 int proxyPort = 8080; 3549 if (data.length > 1) { 3550 try { 3551 proxyPort = Integer.parseInt(data[1]); 3552 } catch (NumberFormatException e) { 3553 return; 3554 } 3555 } 3556 ProxyInfo p = new ProxyInfo(data[0], proxyPort, ""); 3557 setGlobalProxy(p); 3558 } 3559 } 3560 sendProxyBroadcast(ProxyInfo proxy)3561 private void sendProxyBroadcast(ProxyInfo proxy) { 3562 if (proxy == null) proxy = new ProxyInfo("", 0, ""); 3563 if (mPacManager.setCurrentProxyScriptUrl(proxy)) return; 3564 if (DBG) log("sending Proxy Broadcast for " + proxy); 3565 Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); 3566 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | 3567 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 3568 intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy); 3569 final long ident = Binder.clearCallingIdentity(); 3570 try { 3571 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 3572 } finally { 3573 Binder.restoreCallingIdentity(ident); 3574 } 3575 } 3576 3577 private static class SettingsObserver extends ContentObserver { 3578 final private HashMap<Uri, Integer> mUriEventMap; 3579 final private Context mContext; 3580 final private Handler mHandler; 3581 SettingsObserver(Context context, Handler handler)3582 SettingsObserver(Context context, Handler handler) { 3583 super(null); 3584 mUriEventMap = new HashMap<Uri, Integer>(); 3585 mContext = context; 3586 mHandler = handler; 3587 } 3588 observe(Uri uri, int what)3589 void observe(Uri uri, int what) { 3590 mUriEventMap.put(uri, what); 3591 final ContentResolver resolver = mContext.getContentResolver(); 3592 resolver.registerContentObserver(uri, false, this); 3593 } 3594 3595 @Override onChange(boolean selfChange)3596 public void onChange(boolean selfChange) { 3597 Slog.wtf(TAG, "Should never be reached."); 3598 } 3599 3600 @Override onChange(boolean selfChange, Uri uri)3601 public void onChange(boolean selfChange, Uri uri) { 3602 final Integer what = mUriEventMap.get(uri); 3603 if (what != null) { 3604 mHandler.obtainMessage(what.intValue()).sendToTarget(); 3605 } else { 3606 loge("No matching event to send for URI=" + uri); 3607 } 3608 } 3609 } 3610 log(String s)3611 private static void log(String s) { 3612 Slog.d(TAG, s); 3613 } 3614 loge(String s)3615 private static void loge(String s) { 3616 Slog.e(TAG, s); 3617 } 3618 loge(String s, Throwable t)3619 private static void loge(String s, Throwable t) { 3620 Slog.e(TAG, s, t); 3621 } 3622 3623 /** 3624 * Prepare for a VPN application. 3625 * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId}, 3626 * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required. 3627 * 3628 * @param oldPackage Package name of the application which currently controls VPN, which will 3629 * be replaced. If there is no such application, this should should either be 3630 * {@code null} or {@link VpnConfig.LEGACY_VPN}. 3631 * @param newPackage Package name of the application which should gain control of VPN, or 3632 * {@code null} to disable. 3633 * @param userId User for whom to prepare the new VPN. 3634 * 3635 * @hide 3636 */ 3637 @Override prepareVpn(@ullable String oldPackage, @Nullable String newPackage, int userId)3638 public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage, 3639 int userId) { 3640 enforceCrossUserPermission(userId); 3641 3642 synchronized (mVpns) { 3643 throwIfLockdownEnabled(); 3644 Vpn vpn = mVpns.get(userId); 3645 if (vpn != null) { 3646 return vpn.prepare(oldPackage, newPackage); 3647 } else { 3648 return false; 3649 } 3650 } 3651 } 3652 3653 /** 3654 * Set whether the VPN package has the ability to launch VPNs without user intervention. 3655 * This method is used by system-privileged apps. 3656 * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId}, 3657 * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required. 3658 * 3659 * @param packageName The package for which authorization state should change. 3660 * @param userId User for whom {@code packageName} is installed. 3661 * @param authorized {@code true} if this app should be able to start a VPN connection without 3662 * explicit user approval, {@code false} if not. 3663 * 3664 * @hide 3665 */ 3666 @Override setVpnPackageAuthorization(String packageName, int userId, boolean authorized)3667 public void setVpnPackageAuthorization(String packageName, int userId, boolean authorized) { 3668 enforceCrossUserPermission(userId); 3669 3670 synchronized (mVpns) { 3671 Vpn vpn = mVpns.get(userId); 3672 if (vpn != null) { 3673 vpn.setPackageAuthorization(packageName, authorized); 3674 } 3675 } 3676 } 3677 3678 /** 3679 * Configure a TUN interface and return its file descriptor. Parameters 3680 * are encoded and opaque to this class. This method is used by VpnBuilder 3681 * and not available in ConnectivityManager. Permissions are checked in 3682 * Vpn class. 3683 * @hide 3684 */ 3685 @Override establishVpn(VpnConfig config)3686 public ParcelFileDescriptor establishVpn(VpnConfig config) { 3687 int user = UserHandle.getUserId(Binder.getCallingUid()); 3688 synchronized (mVpns) { 3689 throwIfLockdownEnabled(); 3690 return mVpns.get(user).establish(config); 3691 } 3692 } 3693 3694 /** 3695 * Start legacy VPN, controlling native daemons as needed. Creates a 3696 * secondary thread to perform connection work, returning quickly. 3697 */ 3698 @Override startLegacyVpn(VpnProfile profile)3699 public void startLegacyVpn(VpnProfile profile) { 3700 int user = UserHandle.getUserId(Binder.getCallingUid()); 3701 final LinkProperties egress = getActiveLinkProperties(); 3702 if (egress == null) { 3703 throw new IllegalStateException("Missing active network connection"); 3704 } 3705 synchronized (mVpns) { 3706 throwIfLockdownEnabled(); 3707 mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress); 3708 } 3709 } 3710 3711 /** 3712 * Return the information of the ongoing legacy VPN. This method is used 3713 * by VpnSettings and not available in ConnectivityManager. Permissions 3714 * are checked in Vpn class. 3715 */ 3716 @Override getLegacyVpnInfo(int userId)3717 public LegacyVpnInfo getLegacyVpnInfo(int userId) { 3718 enforceCrossUserPermission(userId); 3719 3720 synchronized (mVpns) { 3721 return mVpns.get(userId).getLegacyVpnInfo(); 3722 } 3723 } 3724 3725 /** 3726 * Return the information of all ongoing VPNs. This method is used by NetworkStatsService 3727 * and not available in ConnectivityManager. 3728 */ 3729 @Override getAllVpnInfo()3730 public VpnInfo[] getAllVpnInfo() { 3731 enforceConnectivityInternalPermission(); 3732 synchronized (mVpns) { 3733 if (mLockdownEnabled) { 3734 return new VpnInfo[0]; 3735 } 3736 3737 List<VpnInfo> infoList = new ArrayList<>(); 3738 for (int i = 0; i < mVpns.size(); i++) { 3739 VpnInfo info = createVpnInfo(mVpns.valueAt(i)); 3740 if (info != null) { 3741 infoList.add(info); 3742 } 3743 } 3744 return infoList.toArray(new VpnInfo[infoList.size()]); 3745 } 3746 } 3747 3748 /** 3749 * @return VPN information for accounting, or null if we can't retrieve all required 3750 * information, e.g primary underlying iface. 3751 */ 3752 @Nullable createVpnInfo(Vpn vpn)3753 private VpnInfo createVpnInfo(Vpn vpn) { 3754 VpnInfo info = vpn.getVpnInfo(); 3755 if (info == null) { 3756 return null; 3757 } 3758 Network[] underlyingNetworks = vpn.getUnderlyingNetworks(); 3759 // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret 3760 // the underlyingNetworks list. 3761 if (underlyingNetworks == null) { 3762 NetworkAgentInfo defaultNetwork = getDefaultNetwork(); 3763 if (defaultNetwork != null && defaultNetwork.linkProperties != null) { 3764 info.primaryUnderlyingIface = getDefaultNetwork().linkProperties.getInterfaceName(); 3765 } 3766 } else if (underlyingNetworks.length > 0) { 3767 LinkProperties linkProperties = getLinkProperties(underlyingNetworks[0]); 3768 if (linkProperties != null) { 3769 info.primaryUnderlyingIface = linkProperties.getInterfaceName(); 3770 } 3771 } 3772 return info.primaryUnderlyingIface == null ? null : info; 3773 } 3774 3775 /** 3776 * Returns the information of the ongoing VPN for {@code userId}. This method is used by 3777 * VpnDialogs and not available in ConnectivityManager. 3778 * Permissions are checked in Vpn class. 3779 * @hide 3780 */ 3781 @Override getVpnConfig(int userId)3782 public VpnConfig getVpnConfig(int userId) { 3783 enforceCrossUserPermission(userId); 3784 synchronized (mVpns) { 3785 Vpn vpn = mVpns.get(userId); 3786 if (vpn != null) { 3787 return vpn.getVpnConfig(); 3788 } else { 3789 return null; 3790 } 3791 } 3792 } 3793 3794 /** 3795 * Ask all VPN objects to recompute and update their capabilities. 3796 * 3797 * When underlying networks change, VPNs may have to update capabilities to reflect things 3798 * like the metered bit, their transports, and so on. This asks the VPN objects to update 3799 * their capabilities, and as this will cause them to send messages to the ConnectivityService 3800 * handler thread through their agent, this is asynchronous. When the capabilities objects 3801 * are computed they will be up-to-date as they are computed synchronously from here and 3802 * this is running on the ConnectivityService thread. 3803 * TODO : Fix this and call updateCapabilities inline to remove out-of-order events. 3804 */ updateAllVpnsCapabilities()3805 private void updateAllVpnsCapabilities() { 3806 synchronized (mVpns) { 3807 for (int i = 0; i < mVpns.size(); i++) { 3808 final Vpn vpn = mVpns.valueAt(i); 3809 vpn.updateCapabilities(); 3810 } 3811 } 3812 } 3813 3814 @Override updateLockdownVpn()3815 public boolean updateLockdownVpn() { 3816 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 3817 Slog.w(TAG, "Lockdown VPN only available to AID_SYSTEM"); 3818 return false; 3819 } 3820 3821 synchronized (mVpns) { 3822 // Tear down existing lockdown if profile was removed 3823 mLockdownEnabled = LockdownVpnTracker.isEnabled(); 3824 if (mLockdownEnabled) { 3825 byte[] profileTag = mKeyStore.get(Credentials.LOCKDOWN_VPN); 3826 if (profileTag == null) { 3827 Slog.e(TAG, "Lockdown VPN configured but cannot be read from keystore"); 3828 return false; 3829 } 3830 String profileName = new String(profileTag); 3831 final VpnProfile profile = VpnProfile.decode( 3832 profileName, mKeyStore.get(Credentials.VPN + profileName)); 3833 if (profile == null) { 3834 Slog.e(TAG, "Lockdown VPN configured invalid profile " + profileName); 3835 setLockdownTracker(null); 3836 return true; 3837 } 3838 int user = UserHandle.getUserId(Binder.getCallingUid()); 3839 Vpn vpn = mVpns.get(user); 3840 if (vpn == null) { 3841 Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown"); 3842 return false; 3843 } 3844 setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, vpn, profile)); 3845 } else { 3846 setLockdownTracker(null); 3847 } 3848 } 3849 3850 return true; 3851 } 3852 3853 /** 3854 * Internally set new {@link LockdownVpnTracker}, shutting down any existing 3855 * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown. 3856 */ 3857 @GuardedBy("mVpns") setLockdownTracker(LockdownVpnTracker tracker)3858 private void setLockdownTracker(LockdownVpnTracker tracker) { 3859 // Shutdown any existing tracker 3860 final LockdownVpnTracker existing = mLockdownTracker; 3861 mLockdownTracker = null; 3862 if (existing != null) { 3863 existing.shutdown(); 3864 } 3865 3866 if (tracker != null) { 3867 mLockdownTracker = tracker; 3868 mLockdownTracker.init(); 3869 } 3870 } 3871 3872 @GuardedBy("mVpns") throwIfLockdownEnabled()3873 private void throwIfLockdownEnabled() { 3874 if (mLockdownEnabled) { 3875 throw new IllegalStateException("Unavailable in lockdown mode"); 3876 } 3877 } 3878 3879 /** 3880 * Starts the always-on VPN {@link VpnService} for user {@param userId}, which should perform 3881 * some setup and then call {@code establish()} to connect. 3882 * 3883 * @return {@code true} if the service was started, the service was already connected, or there 3884 * was no always-on VPN to start. {@code false} otherwise. 3885 */ startAlwaysOnVpn(int userId)3886 private boolean startAlwaysOnVpn(int userId) { 3887 synchronized (mVpns) { 3888 Vpn vpn = mVpns.get(userId); 3889 if (vpn == null) { 3890 // Shouldn't happen as all codepaths that point here should have checked the Vpn 3891 // exists already. 3892 Slog.wtf(TAG, "User " + userId + " has no Vpn configuration"); 3893 return false; 3894 } 3895 3896 return vpn.startAlwaysOnVpn(); 3897 } 3898 } 3899 3900 @Override isAlwaysOnVpnPackageSupported(int userId, String packageName)3901 public boolean isAlwaysOnVpnPackageSupported(int userId, String packageName) { 3902 enforceSettingsPermission(); 3903 enforceCrossUserPermission(userId); 3904 3905 synchronized (mVpns) { 3906 Vpn vpn = mVpns.get(userId); 3907 if (vpn == null) { 3908 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 3909 return false; 3910 } 3911 return vpn.isAlwaysOnPackageSupported(packageName); 3912 } 3913 } 3914 3915 @Override setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown)3916 public boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown) { 3917 enforceConnectivityInternalPermission(); 3918 enforceCrossUserPermission(userId); 3919 3920 synchronized (mVpns) { 3921 // Can't set always-on VPN if legacy VPN is already in lockdown mode. 3922 if (LockdownVpnTracker.isEnabled()) { 3923 return false; 3924 } 3925 3926 Vpn vpn = mVpns.get(userId); 3927 if (vpn == null) { 3928 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 3929 return false; 3930 } 3931 if (!vpn.setAlwaysOnPackage(packageName, lockdown)) { 3932 return false; 3933 } 3934 if (!startAlwaysOnVpn(userId)) { 3935 vpn.setAlwaysOnPackage(null, false); 3936 return false; 3937 } 3938 } 3939 return true; 3940 } 3941 3942 @Override getAlwaysOnVpnPackage(int userId)3943 public String getAlwaysOnVpnPackage(int userId) { 3944 enforceConnectivityInternalPermission(); 3945 enforceCrossUserPermission(userId); 3946 3947 synchronized (mVpns) { 3948 Vpn vpn = mVpns.get(userId); 3949 if (vpn == null) { 3950 Slog.w(TAG, "User " + userId + " has no Vpn configuration"); 3951 return null; 3952 } 3953 return vpn.getAlwaysOnPackage(); 3954 } 3955 } 3956 3957 @Override checkMobileProvisioning(int suggestedTimeOutMs)3958 public int checkMobileProvisioning(int suggestedTimeOutMs) { 3959 // TODO: Remove? Any reason to trigger a provisioning check? 3960 return -1; 3961 } 3962 3963 /** Location to an updatable file listing carrier provisioning urls. 3964 * An example: 3965 * 3966 * <?xml version="1.0" encoding="utf-8"?> 3967 * <provisioningUrls> 3968 * <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&iccid=%1$s&imei=%2$s</provisioningUrl> 3969 * </provisioningUrls> 3970 */ 3971 private static final String PROVISIONING_URL_PATH = 3972 "/data/misc/radio/provisioning_urls.xml"; 3973 private final File mProvisioningUrlFile = new File(PROVISIONING_URL_PATH); 3974 3975 /** XML tag for root element. */ 3976 private static final String TAG_PROVISIONING_URLS = "provisioningUrls"; 3977 /** XML tag for individual url */ 3978 private static final String TAG_PROVISIONING_URL = "provisioningUrl"; 3979 /** XML attribute for mcc */ 3980 private static final String ATTR_MCC = "mcc"; 3981 /** XML attribute for mnc */ 3982 private static final String ATTR_MNC = "mnc"; 3983 getProvisioningUrlBaseFromFile()3984 private String getProvisioningUrlBaseFromFile() { 3985 FileReader fileReader = null; 3986 XmlPullParser parser = null; 3987 Configuration config = mContext.getResources().getConfiguration(); 3988 3989 try { 3990 fileReader = new FileReader(mProvisioningUrlFile); 3991 parser = Xml.newPullParser(); 3992 parser.setInput(fileReader); 3993 XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS); 3994 3995 while (true) { 3996 XmlUtils.nextElement(parser); 3997 3998 String element = parser.getName(); 3999 if (element == null) break; 4000 4001 if (element.equals(TAG_PROVISIONING_URL)) { 4002 String mcc = parser.getAttributeValue(null, ATTR_MCC); 4003 try { 4004 if (mcc != null && Integer.parseInt(mcc) == config.mcc) { 4005 String mnc = parser.getAttributeValue(null, ATTR_MNC); 4006 if (mnc != null && Integer.parseInt(mnc) == config.mnc) { 4007 parser.next(); 4008 if (parser.getEventType() == XmlPullParser.TEXT) { 4009 return parser.getText(); 4010 } 4011 } 4012 } 4013 } catch (NumberFormatException e) { 4014 loge("NumberFormatException in getProvisioningUrlBaseFromFile: " + e); 4015 } 4016 } 4017 } 4018 return null; 4019 } catch (FileNotFoundException e) { 4020 loge("Carrier Provisioning Urls file not found"); 4021 } catch (XmlPullParserException e) { 4022 loge("Xml parser exception reading Carrier Provisioning Urls file: " + e); 4023 } catch (IOException e) { 4024 loge("I/O exception reading Carrier Provisioning Urls file: " + e); 4025 } finally { 4026 if (fileReader != null) { 4027 try { 4028 fileReader.close(); 4029 } catch (IOException e) {} 4030 } 4031 } 4032 return null; 4033 } 4034 4035 @Override getMobileProvisioningUrl()4036 public String getMobileProvisioningUrl() { 4037 enforceConnectivityInternalPermission(); 4038 String url = getProvisioningUrlBaseFromFile(); 4039 if (TextUtils.isEmpty(url)) { 4040 url = mContext.getResources().getString(R.string.mobile_provisioning_url); 4041 log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url); 4042 } else { 4043 log("getMobileProvisioningUrl: mobile_provisioning_url from File =" + url); 4044 } 4045 // populate the iccid, imei and phone number in the provisioning url. 4046 if (!TextUtils.isEmpty(url)) { 4047 String phoneNumber = mTelephonyManager.getLine1Number(); 4048 if (TextUtils.isEmpty(phoneNumber)) { 4049 phoneNumber = "0000000000"; 4050 } 4051 url = String.format(url, 4052 mTelephonyManager.getSimSerialNumber() /* ICCID */, 4053 mTelephonyManager.getDeviceId() /* IMEI */, 4054 phoneNumber /* Phone numer */); 4055 } 4056 4057 return url; 4058 } 4059 4060 @Override setProvisioningNotificationVisible(boolean visible, int networkType, String action)4061 public void setProvisioningNotificationVisible(boolean visible, int networkType, 4062 String action) { 4063 enforceConnectivityInternalPermission(); 4064 if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 4065 return; 4066 } 4067 final long ident = Binder.clearCallingIdentity(); 4068 try { 4069 // Concatenate the range of types onto the range of NetIDs. 4070 int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); 4071 mNotifier.setProvNotificationVisible(visible, id, action); 4072 } finally { 4073 Binder.restoreCallingIdentity(ident); 4074 } 4075 } 4076 4077 @Override setAirplaneMode(boolean enable)4078 public void setAirplaneMode(boolean enable) { 4079 enforceConnectivityInternalPermission(); 4080 final long ident = Binder.clearCallingIdentity(); 4081 try { 4082 final ContentResolver cr = mContext.getContentResolver(); 4083 Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable)); 4084 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 4085 intent.putExtra("state", enable); 4086 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 4087 } finally { 4088 Binder.restoreCallingIdentity(ident); 4089 } 4090 } 4091 onUserStart(int userId)4092 private void onUserStart(int userId) { 4093 synchronized (mVpns) { 4094 Vpn userVpn = mVpns.get(userId); 4095 if (userVpn != null) { 4096 loge("Starting user already has a VPN"); 4097 return; 4098 } 4099 userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, userId); 4100 mVpns.put(userId, userVpn); 4101 if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { 4102 updateLockdownVpn(); 4103 } 4104 } 4105 } 4106 onUserStop(int userId)4107 private void onUserStop(int userId) { 4108 synchronized (mVpns) { 4109 Vpn userVpn = mVpns.get(userId); 4110 if (userVpn == null) { 4111 loge("Stopped user has no VPN"); 4112 return; 4113 } 4114 userVpn.onUserStopped(); 4115 mVpns.delete(userId); 4116 } 4117 } 4118 onUserAdded(int userId)4119 private void onUserAdded(int userId) { 4120 synchronized (mVpns) { 4121 final int vpnsSize = mVpns.size(); 4122 for (int i = 0; i < vpnsSize; i++) { 4123 Vpn vpn = mVpns.valueAt(i); 4124 vpn.onUserAdded(userId); 4125 } 4126 } 4127 } 4128 onUserRemoved(int userId)4129 private void onUserRemoved(int userId) { 4130 synchronized (mVpns) { 4131 final int vpnsSize = mVpns.size(); 4132 for (int i = 0; i < vpnsSize; i++) { 4133 Vpn vpn = mVpns.valueAt(i); 4134 vpn.onUserRemoved(userId); 4135 } 4136 } 4137 } 4138 onUserUnlocked(int userId)4139 private void onUserUnlocked(int userId) { 4140 synchronized (mVpns) { 4141 // User present may be sent because of an unlock, which might mean an unlocked keystore. 4142 if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { 4143 updateLockdownVpn(); 4144 } else { 4145 startAlwaysOnVpn(userId); 4146 } 4147 } 4148 } 4149 4150 private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() { 4151 @Override 4152 public void onReceive(Context context, Intent intent) { 4153 final String action = intent.getAction(); 4154 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 4155 if (userId == UserHandle.USER_NULL) return; 4156 4157 if (Intent.ACTION_USER_STARTED.equals(action)) { 4158 onUserStart(userId); 4159 } else if (Intent.ACTION_USER_STOPPED.equals(action)) { 4160 onUserStop(userId); 4161 } else if (Intent.ACTION_USER_ADDED.equals(action)) { 4162 onUserAdded(userId); 4163 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 4164 onUserRemoved(userId); 4165 } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) { 4166 onUserUnlocked(userId); 4167 } 4168 } 4169 }; 4170 4171 private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() { 4172 @Override 4173 public void onReceive(Context context, Intent intent) { 4174 // Try creating lockdown tracker, since user present usually means 4175 // unlocked keystore. 4176 updateLockdownVpn(); 4177 mContext.unregisterReceiver(this); 4178 } 4179 }; 4180 4181 private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos = 4182 new HashMap<Messenger, NetworkFactoryInfo>(); 4183 private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = 4184 new HashMap<NetworkRequest, NetworkRequestInfo>(); 4185 4186 private static final int MAX_NETWORK_REQUESTS_PER_UID = 100; 4187 // Map from UID to number of NetworkRequests that UID has filed. 4188 @GuardedBy("mUidToNetworkRequestCount") 4189 private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray(); 4190 4191 private static class NetworkFactoryInfo { 4192 public final String name; 4193 public final Messenger messenger; 4194 public final AsyncChannel asyncChannel; 4195 NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel)4196 public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) { 4197 this.name = name; 4198 this.messenger = messenger; 4199 this.asyncChannel = asyncChannel; 4200 } 4201 } 4202 ensureNetworkRequestHasType(NetworkRequest request)4203 private void ensureNetworkRequestHasType(NetworkRequest request) { 4204 if (request.type == NetworkRequest.Type.NONE) { 4205 throw new IllegalArgumentException( 4206 "All NetworkRequests in ConnectivityService must have a type"); 4207 } 4208 } 4209 4210 /** 4211 * Tracks info about the requester. 4212 * Also used to notice when the calling process dies so we can self-expire 4213 */ 4214 private class NetworkRequestInfo implements IBinder.DeathRecipient { 4215 final NetworkRequest request; 4216 final PendingIntent mPendingIntent; 4217 boolean mPendingIntentSent; 4218 private final IBinder mBinder; 4219 final int mPid; 4220 final int mUid; 4221 final Messenger messenger; 4222 NetworkRequestInfo(NetworkRequest r, PendingIntent pi)4223 NetworkRequestInfo(NetworkRequest r, PendingIntent pi) { 4224 request = r; 4225 ensureNetworkRequestHasType(request); 4226 mPendingIntent = pi; 4227 messenger = null; 4228 mBinder = null; 4229 mPid = getCallingPid(); 4230 mUid = getCallingUid(); 4231 enforceRequestCountLimit(); 4232 } 4233 NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder)4234 NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) { 4235 super(); 4236 messenger = m; 4237 request = r; 4238 ensureNetworkRequestHasType(request); 4239 mBinder = binder; 4240 mPid = getCallingPid(); 4241 mUid = getCallingUid(); 4242 mPendingIntent = null; 4243 enforceRequestCountLimit(); 4244 4245 try { 4246 mBinder.linkToDeath(this, 0); 4247 } catch (RemoteException e) { 4248 binderDied(); 4249 } 4250 } 4251 enforceRequestCountLimit()4252 private void enforceRequestCountLimit() { 4253 synchronized (mUidToNetworkRequestCount) { 4254 int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1; 4255 if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) { 4256 throw new ServiceSpecificException( 4257 ConnectivityManager.Errors.TOO_MANY_REQUESTS); 4258 } 4259 mUidToNetworkRequestCount.put(mUid, networkRequests); 4260 } 4261 } 4262 unlinkDeathRecipient()4263 void unlinkDeathRecipient() { 4264 if (mBinder != null) { 4265 mBinder.unlinkToDeath(this, 0); 4266 } 4267 } 4268 binderDied()4269 public void binderDied() { 4270 log("ConnectivityService NetworkRequestInfo binderDied(" + 4271 request + ", " + mBinder + ")"); 4272 releaseNetworkRequest(request); 4273 } 4274 toString()4275 public String toString() { 4276 return "uid/pid:" + mUid + "/" + mPid + " " + request + 4277 (mPendingIntent == null ? "" : " to trigger " + mPendingIntent); 4278 } 4279 } 4280 ensureRequestableCapabilities(NetworkCapabilities networkCapabilities)4281 private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) { 4282 final String badCapability = networkCapabilities.describeFirstNonRequestableCapability(); 4283 if (badCapability != null) { 4284 throw new IllegalArgumentException("Cannot request network with " + badCapability); 4285 } 4286 } 4287 4288 // This checks that the passed capabilities either do not request a specific SSID, or the 4289 // calling app has permission to do so. ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid)4290 private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, 4291 int callerPid, int callerUid) { 4292 if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) { 4293 throw new SecurityException("Insufficient permissions to request a specific SSID"); 4294 } 4295 } 4296 getSignalStrengthThresholds(NetworkAgentInfo nai)4297 private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) { 4298 final SortedSet<Integer> thresholds = new TreeSet(); 4299 synchronized (nai) { 4300 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 4301 if (nri.request.networkCapabilities.hasSignalStrength() && 4302 nai.satisfiesImmutableCapabilitiesOf(nri.request)) { 4303 thresholds.add(nri.request.networkCapabilities.getSignalStrength()); 4304 } 4305 } 4306 } 4307 return new ArrayList<Integer>(thresholds); 4308 } 4309 updateSignalStrengthThresholds( NetworkAgentInfo nai, String reason, NetworkRequest request)4310 private void updateSignalStrengthThresholds( 4311 NetworkAgentInfo nai, String reason, NetworkRequest request) { 4312 ArrayList<Integer> thresholdsArray = getSignalStrengthThresholds(nai); 4313 Bundle thresholds = new Bundle(); 4314 thresholds.putIntegerArrayList("thresholds", thresholdsArray); 4315 4316 if (VDBG || (DBG && !"CONNECT".equals(reason))) { 4317 String detail; 4318 if (request != null && request.networkCapabilities.hasSignalStrength()) { 4319 detail = reason + " " + request.networkCapabilities.getSignalStrength(); 4320 } else { 4321 detail = reason; 4322 } 4323 log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s", 4324 detail, Arrays.toString(thresholdsArray.toArray()), nai.name())); 4325 } 4326 4327 nai.asyncChannel.sendMessage( 4328 android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS, 4329 0, 0, thresholds); 4330 } 4331 ensureValidNetworkSpecifier(NetworkCapabilities nc)4332 private void ensureValidNetworkSpecifier(NetworkCapabilities nc) { 4333 if (nc == null) { 4334 return; 4335 } 4336 NetworkSpecifier ns = nc.getNetworkSpecifier(); 4337 if (ns == null) { 4338 return; 4339 } 4340 MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns); 4341 ns.assertValidFromUid(Binder.getCallingUid()); 4342 } 4343 4344 @Override requestNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, int timeoutMs, IBinder binder, int legacyType)4345 public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, 4346 Messenger messenger, int timeoutMs, IBinder binder, int legacyType) { 4347 final NetworkRequest.Type type = (networkCapabilities == null) 4348 ? NetworkRequest.Type.TRACK_DEFAULT 4349 : NetworkRequest.Type.REQUEST; 4350 // If the requested networkCapabilities is null, take them instead from 4351 // the default network request. This allows callers to keep track of 4352 // the system default network. 4353 if (type == NetworkRequest.Type.TRACK_DEFAULT) { 4354 networkCapabilities = createDefaultNetworkCapabilitiesForUid(Binder.getCallingUid()); 4355 enforceAccessPermission(); 4356 } else { 4357 networkCapabilities = new NetworkCapabilities(networkCapabilities); 4358 enforceNetworkRequestPermissions(networkCapabilities); 4359 // TODO: this is incorrect. We mark the request as metered or not depending on the state 4360 // of the app when the request is filed, but we never change the request if the app 4361 // changes network state. http://b/29964605 4362 enforceMeteredApnPolicy(networkCapabilities); 4363 } 4364 ensureRequestableCapabilities(networkCapabilities); 4365 ensureSufficientPermissionsForRequest(networkCapabilities, 4366 Binder.getCallingPid(), Binder.getCallingUid()); 4367 // Set the UID range for this request to the single UID of the requester, or to an empty 4368 // set of UIDs if the caller has the appropriate permission and UIDs have not been set. 4369 // This will overwrite any allowed UIDs in the requested capabilities. Though there 4370 // are no visible methods to set the UIDs, an app could use reflection to try and get 4371 // networks for other apps so it's essential that the UIDs are overwritten. 4372 restrictRequestUidsForCaller(networkCapabilities); 4373 4374 if (timeoutMs < 0) { 4375 throw new IllegalArgumentException("Bad timeout specified"); 4376 } 4377 ensureValidNetworkSpecifier(networkCapabilities); 4378 4379 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, 4380 nextNetworkRequestId(), type); 4381 NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder); 4382 if (DBG) log("requestNetwork for " + nri); 4383 4384 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri)); 4385 if (timeoutMs > 0) { 4386 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST, 4387 nri), timeoutMs); 4388 } 4389 return networkRequest; 4390 } 4391 enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities)4392 private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) { 4393 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) { 4394 enforceConnectivityRestrictedNetworksPermission(); 4395 } else { 4396 enforceChangePermission(); 4397 } 4398 } 4399 4400 @Override requestBandwidthUpdate(Network network)4401 public boolean requestBandwidthUpdate(Network network) { 4402 enforceAccessPermission(); 4403 NetworkAgentInfo nai = null; 4404 if (network == null) { 4405 return false; 4406 } 4407 synchronized (mNetworkForNetId) { 4408 nai = mNetworkForNetId.get(network.netId); 4409 } 4410 if (nai != null) { 4411 nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE); 4412 return true; 4413 } 4414 return false; 4415 } 4416 isSystem(int uid)4417 private boolean isSystem(int uid) { 4418 return uid < Process.FIRST_APPLICATION_UID; 4419 } 4420 enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities)4421 private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) { 4422 final int uid = Binder.getCallingUid(); 4423 if (isSystem(uid)) { 4424 // Exemption for system uid. 4425 return; 4426 } 4427 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) { 4428 // Policy already enforced. 4429 return; 4430 } 4431 if (mPolicyManagerInternal.isUidRestrictedOnMeteredNetworks(uid)) { 4432 // If UID is restricted, don't allow them to bring up metered APNs. 4433 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED); 4434 } 4435 } 4436 4437 @Override pendingRequestForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)4438 public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, 4439 PendingIntent operation) { 4440 checkNotNull(operation, "PendingIntent cannot be null."); 4441 networkCapabilities = new NetworkCapabilities(networkCapabilities); 4442 enforceNetworkRequestPermissions(networkCapabilities); 4443 enforceMeteredApnPolicy(networkCapabilities); 4444 ensureRequestableCapabilities(networkCapabilities); 4445 ensureSufficientPermissionsForRequest(networkCapabilities, 4446 Binder.getCallingPid(), Binder.getCallingUid()); 4447 ensureValidNetworkSpecifier(networkCapabilities); 4448 restrictRequestUidsForCaller(networkCapabilities); 4449 4450 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, 4451 nextNetworkRequestId(), NetworkRequest.Type.REQUEST); 4452 NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation); 4453 if (DBG) log("pendingRequest for " + nri); 4454 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT, 4455 nri)); 4456 return networkRequest; 4457 } 4458 releasePendingNetworkRequestWithDelay(PendingIntent operation)4459 private void releasePendingNetworkRequestWithDelay(PendingIntent operation) { 4460 mHandler.sendMessageDelayed( 4461 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 4462 getCallingUid(), 0, operation), mReleasePendingIntentDelayMs); 4463 } 4464 4465 @Override releasePendingNetworkRequest(PendingIntent operation)4466 public void releasePendingNetworkRequest(PendingIntent operation) { 4467 checkNotNull(operation, "PendingIntent cannot be null."); 4468 mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, 4469 getCallingUid(), 0, operation)); 4470 } 4471 4472 // In order to implement the compatibility measure for pre-M apps that call 4473 // WifiManager.enableNetwork(..., true) without also binding to that network explicitly, 4474 // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork. 4475 // This ensures it has permission to do so. hasWifiNetworkListenPermission(NetworkCapabilities nc)4476 private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) { 4477 if (nc == null) { 4478 return false; 4479 } 4480 int[] transportTypes = nc.getTransportTypes(); 4481 if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) { 4482 return false; 4483 } 4484 try { 4485 mContext.enforceCallingOrSelfPermission( 4486 android.Manifest.permission.ACCESS_WIFI_STATE, 4487 "ConnectivityService"); 4488 } catch (SecurityException e) { 4489 return false; 4490 } 4491 return true; 4492 } 4493 4494 @Override listenForNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, IBinder binder)4495 public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, 4496 Messenger messenger, IBinder binder) { 4497 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 4498 enforceAccessPermission(); 4499 } 4500 4501 NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 4502 ensureSufficientPermissionsForRequest(networkCapabilities, 4503 Binder.getCallingPid(), Binder.getCallingUid()); 4504 restrictRequestUidsForCaller(nc); 4505 // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so 4506 // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get 4507 // onLost and onAvailable callbacks when networks move in and out of the background. 4508 // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE 4509 // can't request networks. 4510 restrictBackgroundRequestForCaller(nc); 4511 ensureValidNetworkSpecifier(nc); 4512 4513 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 4514 NetworkRequest.Type.LISTEN); 4515 NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder); 4516 if (VDBG) log("listenForNetwork for " + nri); 4517 4518 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); 4519 return networkRequest; 4520 } 4521 4522 @Override pendingListenForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)4523 public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, 4524 PendingIntent operation) { 4525 checkNotNull(operation, "PendingIntent cannot be null."); 4526 if (!hasWifiNetworkListenPermission(networkCapabilities)) { 4527 enforceAccessPermission(); 4528 } 4529 ensureValidNetworkSpecifier(networkCapabilities); 4530 ensureSufficientPermissionsForRequest(networkCapabilities, 4531 Binder.getCallingPid(), Binder.getCallingUid()); 4532 4533 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 4534 restrictRequestUidsForCaller(nc); 4535 4536 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), 4537 NetworkRequest.Type.LISTEN); 4538 NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation); 4539 if (VDBG) log("pendingListenForNetwork for " + nri); 4540 4541 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); 4542 } 4543 4544 @Override releaseNetworkRequest(NetworkRequest networkRequest)4545 public void releaseNetworkRequest(NetworkRequest networkRequest) { 4546 ensureNetworkRequestHasType(networkRequest); 4547 mHandler.sendMessage(mHandler.obtainMessage( 4548 EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), 0, networkRequest)); 4549 } 4550 4551 @Override registerNetworkFactory(Messenger messenger, String name)4552 public void registerNetworkFactory(Messenger messenger, String name) { 4553 enforceConnectivityInternalPermission(); 4554 NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel()); 4555 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); 4556 } 4557 handleRegisterNetworkFactory(NetworkFactoryInfo nfi)4558 private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { 4559 if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); 4560 mNetworkFactoryInfos.put(nfi.messenger, nfi); 4561 nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger); 4562 } 4563 4564 @Override unregisterNetworkFactory(Messenger messenger)4565 public void unregisterNetworkFactory(Messenger messenger) { 4566 enforceConnectivityInternalPermission(); 4567 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger)); 4568 } 4569 handleUnregisterNetworkFactory(Messenger messenger)4570 private void handleUnregisterNetworkFactory(Messenger messenger) { 4571 NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger); 4572 if (nfi == null) { 4573 loge("Failed to find Messenger in unregisterNetworkFactory"); 4574 return; 4575 } 4576 if (DBG) log("unregisterNetworkFactory for " + nfi.name); 4577 } 4578 4579 /** 4580 * NetworkAgentInfo supporting a request by requestId. 4581 * These have already been vetted (their Capabilities satisfy the request) 4582 * and the are the highest scored network available. 4583 * the are keyed off the Requests requestId. 4584 */ 4585 // NOTE: Accessed on multiple threads, must be synchronized on itself. 4586 @GuardedBy("mNetworkForRequestId") 4587 private final SparseArray<NetworkAgentInfo> mNetworkForRequestId = 4588 new SparseArray<NetworkAgentInfo>(); 4589 4590 // NOTE: Accessed on multiple threads, must be synchronized on itself. 4591 @GuardedBy("mNetworkForNetId") 4592 private final SparseArray<NetworkAgentInfo> mNetworkForNetId = 4593 new SparseArray<NetworkAgentInfo>(); 4594 // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId. 4595 // An entry is first added to mNetIdInUse, prior to mNetworkForNetId, so 4596 // there may not be a strict 1:1 correlation between the two. 4597 @GuardedBy("mNetworkForNetId") 4598 private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray(); 4599 4600 // NetworkAgentInfo keyed off its connecting messenger 4601 // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays 4602 // NOTE: Only should be accessed on ConnectivityServiceThread, except dump(). 4603 private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos = 4604 new HashMap<Messenger, NetworkAgentInfo>(); 4605 4606 @GuardedBy("mBlockedAppUids") 4607 private final HashSet<Integer> mBlockedAppUids = new HashSet(); 4608 4609 // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated. 4610 private final NetworkRequest mDefaultRequest; 4611 4612 // Request used to optionally keep mobile data active even when higher 4613 // priority networks like Wi-Fi are active. 4614 private final NetworkRequest mDefaultMobileDataRequest; 4615 getNetworkForRequest(int requestId)4616 private NetworkAgentInfo getNetworkForRequest(int requestId) { 4617 synchronized (mNetworkForRequestId) { 4618 return mNetworkForRequestId.get(requestId); 4619 } 4620 } 4621 clearNetworkForRequest(int requestId)4622 private void clearNetworkForRequest(int requestId) { 4623 synchronized (mNetworkForRequestId) { 4624 mNetworkForRequestId.remove(requestId); 4625 } 4626 } 4627 setNetworkForRequest(int requestId, NetworkAgentInfo nai)4628 private void setNetworkForRequest(int requestId, NetworkAgentInfo nai) { 4629 synchronized (mNetworkForRequestId) { 4630 mNetworkForRequestId.put(requestId, nai); 4631 } 4632 } 4633 getDefaultNetwork()4634 private NetworkAgentInfo getDefaultNetwork() { 4635 return getNetworkForRequest(mDefaultRequest.requestId); 4636 } 4637 isDefaultNetwork(NetworkAgentInfo nai)4638 private boolean isDefaultNetwork(NetworkAgentInfo nai) { 4639 return nai == getDefaultNetwork(); 4640 } 4641 isDefaultRequest(NetworkRequestInfo nri)4642 private boolean isDefaultRequest(NetworkRequestInfo nri) { 4643 return nri.request.requestId == mDefaultRequest.requestId; 4644 } 4645 registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc)4646 public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, 4647 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 4648 int currentScore, NetworkMisc networkMisc) { 4649 enforceConnectivityInternalPermission(); 4650 4651 LinkProperties lp = new LinkProperties(linkProperties); 4652 lp.ensureDirectlyConnectedRoutes(); 4653 // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network 4654 // satisfies mDefaultRequest. 4655 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); 4656 final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), 4657 new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore, 4658 mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this); 4659 // Make sure the network capabilities reflect what the agent info says. 4660 nai.networkCapabilities = mixInCapabilities(nai, nc); 4661 synchronized (this) { 4662 nai.networkMonitor.systemReady = mSystemReady; 4663 } 4664 final String extraInfo = networkInfo.getExtraInfo(); 4665 final String name = TextUtils.isEmpty(extraInfo) 4666 ? nai.networkCapabilities.getSSID() : extraInfo; 4667 addValidationLogs(nai.networkMonitor.getValidationLogs(), nai.network, name); 4668 if (DBG) log("registerNetworkAgent " + nai); 4669 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai)); 4670 return nai.network.netId; 4671 } 4672 handleRegisterNetworkAgent(NetworkAgentInfo nai)4673 private void handleRegisterNetworkAgent(NetworkAgentInfo nai) { 4674 if (VDBG) log("Got NetworkAgent Messenger"); 4675 mNetworkAgentInfos.put(nai.messenger, nai); 4676 synchronized (mNetworkForNetId) { 4677 mNetworkForNetId.put(nai.network.netId, nai); 4678 } 4679 nai.asyncChannel.connect(mContext, mTrackerHandler, nai.messenger); 4680 NetworkInfo networkInfo = nai.networkInfo; 4681 nai.networkInfo = null; 4682 updateNetworkInfo(nai, networkInfo); 4683 updateUids(nai, null, nai.networkCapabilities); 4684 } 4685 updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp)4686 private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp) { 4687 LinkProperties newLp = new LinkProperties(networkAgent.linkProperties); 4688 int netId = networkAgent.network.netId; 4689 4690 // The NetworkAgentInfo does not know whether clatd is running on its network or not. Before 4691 // we do anything else, make sure its LinkProperties are accurate. 4692 if (networkAgent.clatd != null) { 4693 networkAgent.clatd.fixupLinkProperties(oldLp, newLp); 4694 } 4695 4696 updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities); 4697 updateMtu(newLp, oldLp); 4698 // TODO - figure out what to do for clat 4699 // for (LinkProperties lp : newLp.getStackedLinks()) { 4700 // updateMtu(lp, null); 4701 // } 4702 updateTcpBufferSizes(networkAgent); 4703 4704 updateRoutes(newLp, oldLp, netId); 4705 updateDnses(newLp, oldLp, netId); 4706 // Make sure LinkProperties represents the latest private DNS status. 4707 // This does not need to be done before updateDnses because the 4708 // LinkProperties are not the source of the private DNS configuration. 4709 // updateDnses will fetch the private DNS configuration from DnsManager. 4710 mDnsManager.updatePrivateDnsStatus(netId, newLp); 4711 4712 // Start or stop clat accordingly to network state. 4713 networkAgent.updateClat(mNetd); 4714 if (isDefaultNetwork(networkAgent)) { 4715 handleApplyDefaultProxy(newLp.getHttpProxy()); 4716 } else { 4717 updateProxy(newLp, oldLp, networkAgent); 4718 } 4719 // TODO - move this check to cover the whole function 4720 if (!Objects.equals(newLp, oldLp)) { 4721 synchronized (networkAgent) { 4722 networkAgent.linkProperties = newLp; 4723 } 4724 notifyIfacesChangedForNetworkStats(); 4725 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED); 4726 } 4727 4728 mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent); 4729 } 4730 wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add)4731 private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) { 4732 // Marks are only available on WiFi interaces. Checking for 4733 // marks on unsupported interfaces is harmless. 4734 if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { 4735 return; 4736 } 4737 4738 int mark = mContext.getResources().getInteger( 4739 com.android.internal.R.integer.config_networkWakeupPacketMark); 4740 int mask = mContext.getResources().getInteger( 4741 com.android.internal.R.integer.config_networkWakeupPacketMask); 4742 4743 // Mask/mark of zero will not detect anything interesting. 4744 // Don't install rules unless both values are nonzero. 4745 if (mark == 0 || mask == 0) { 4746 return; 4747 } 4748 4749 final String prefix = "iface:" + iface; 4750 try { 4751 if (add) { 4752 mNetd.getNetdService().wakeupAddInterface(iface, prefix, mark, mask); 4753 } else { 4754 mNetd.getNetdService().wakeupDelInterface(iface, prefix, mark, mask); 4755 } 4756 } catch (Exception e) { 4757 loge("Exception modifying wakeup packet monitoring: " + e); 4758 } 4759 4760 } 4761 updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId, NetworkCapabilities caps)4762 private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId, 4763 NetworkCapabilities caps) { 4764 CompareResult<String> interfaceDiff = new CompareResult<String>( 4765 oldLp != null ? oldLp.getAllInterfaceNames() : null, 4766 newLp != null ? newLp.getAllInterfaceNames() : null); 4767 for (String iface : interfaceDiff.added) { 4768 try { 4769 if (DBG) log("Adding iface " + iface + " to network " + netId); 4770 mNetd.addInterfaceToNetwork(iface, netId); 4771 wakeupModifyInterface(iface, caps, true); 4772 } catch (Exception e) { 4773 loge("Exception adding interface: " + e); 4774 } 4775 } 4776 for (String iface : interfaceDiff.removed) { 4777 try { 4778 if (DBG) log("Removing iface " + iface + " from network " + netId); 4779 wakeupModifyInterface(iface, caps, false); 4780 mNetd.removeInterfaceFromNetwork(iface, netId); 4781 } catch (Exception e) { 4782 loge("Exception removing interface: " + e); 4783 } 4784 } 4785 } 4786 4787 /** 4788 * Have netd update routes from oldLp to newLp. 4789 * @return true if routes changed between oldLp and newLp 4790 */ updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId)4791 private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) { 4792 // Compare the route diff to determine which routes should be added and removed. 4793 CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>( 4794 oldLp != null ? oldLp.getAllRoutes() : null, 4795 newLp != null ? newLp.getAllRoutes() : null); 4796 4797 // add routes before removing old in case it helps with continuous connectivity 4798 4799 // do this twice, adding non-nexthop routes first, then routes they are dependent on 4800 for (RouteInfo route : routeDiff.added) { 4801 if (route.hasGateway()) continue; 4802 if (VDBG) log("Adding Route [" + route + "] to network " + netId); 4803 try { 4804 mNetd.addRoute(netId, route); 4805 } catch (Exception e) { 4806 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) { 4807 loge("Exception in addRoute for non-gateway: " + e); 4808 } 4809 } 4810 } 4811 for (RouteInfo route : routeDiff.added) { 4812 if (route.hasGateway() == false) continue; 4813 if (VDBG) log("Adding Route [" + route + "] to network " + netId); 4814 try { 4815 mNetd.addRoute(netId, route); 4816 } catch (Exception e) { 4817 if ((route.getGateway() instanceof Inet4Address) || VDBG) { 4818 loge("Exception in addRoute for gateway: " + e); 4819 } 4820 } 4821 } 4822 4823 for (RouteInfo route : routeDiff.removed) { 4824 if (VDBG) log("Removing Route [" + route + "] from network " + netId); 4825 try { 4826 mNetd.removeRoute(netId, route); 4827 } catch (Exception e) { 4828 loge("Exception in removeRoute: " + e); 4829 } 4830 } 4831 return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty(); 4832 } 4833 updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId)4834 private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) { 4835 if (oldLp != null && newLp.isIdenticalDnses(oldLp)) { 4836 return; // no updating necessary 4837 } 4838 4839 final NetworkAgentInfo defaultNai = getDefaultNetwork(); 4840 final boolean isDefaultNetwork = (defaultNai != null && defaultNai.network.netId == netId); 4841 4842 if (DBG) { 4843 final Collection<InetAddress> dnses = newLp.getDnsServers(); 4844 log("Setting DNS servers for network " + netId + " to " + dnses); 4845 } 4846 try { 4847 mDnsManager.setDnsConfigurationForNetwork(netId, newLp, isDefaultNetwork); 4848 } catch (Exception e) { 4849 loge("Exception in setDnsConfigurationForNetwork: " + e); 4850 } 4851 } 4852 getNetworkPermission(NetworkCapabilities nc)4853 private String getNetworkPermission(NetworkCapabilities nc) { 4854 // TODO: make these permission strings AIDL constants instead. 4855 if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { 4856 return NetworkManagementService.PERMISSION_SYSTEM; 4857 } 4858 if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) { 4859 return NetworkManagementService.PERMISSION_NETWORK; 4860 } 4861 return null; 4862 } 4863 4864 /** 4865 * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are 4866 * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal, 4867 * and foreground status). 4868 */ mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc)4869 private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) { 4870 // Once a NetworkAgent is connected, complain if some immutable capabilities are removed. 4871 // Don't complain for VPNs since they're not driven by requests and there is no risk of 4872 // causing a connect/teardown loop. 4873 // TODO: remove this altogether and make it the responsibility of the NetworkFactories to 4874 // avoid connect/teardown loops. 4875 if (nai.everConnected && 4876 !nai.isVPN() && 4877 !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) { 4878 // TODO: consider not complaining when a network agent degrades its capabilities if this 4879 // does not cause any request (that is not a listen) currently matching that agent to 4880 // stop being matched by the updated agent. 4881 String diff = nai.networkCapabilities.describeImmutableDifferences(nc); 4882 if (!TextUtils.isEmpty(diff)) { 4883 Slog.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff); 4884 } 4885 } 4886 4887 // Don't modify caller's NetworkCapabilities. 4888 NetworkCapabilities newNc = new NetworkCapabilities(nc); 4889 if (nai.lastValidated) { 4890 newNc.addCapability(NET_CAPABILITY_VALIDATED); 4891 } else { 4892 newNc.removeCapability(NET_CAPABILITY_VALIDATED); 4893 } 4894 if (nai.lastCaptivePortalDetected) { 4895 newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 4896 } else { 4897 newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); 4898 } 4899 if (nai.isBackgroundNetwork()) { 4900 newNc.removeCapability(NET_CAPABILITY_FOREGROUND); 4901 } else { 4902 newNc.addCapability(NET_CAPABILITY_FOREGROUND); 4903 } 4904 if (nai.isSuspended()) { 4905 newNc.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); 4906 } else { 4907 newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED); 4908 } 4909 4910 return newNc; 4911 } 4912 4913 /** 4914 * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically: 4915 * 4916 * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the 4917 * capabilities we manage and store in {@code nai}, such as validated status and captive 4918 * portal status) 4919 * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and 4920 * potentially triggers rematches. 4921 * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the 4922 * change.) 4923 * 4924 * @param oldScore score of the network before any of the changes that prompted us 4925 * to call this function. 4926 * @param nai the network having its capabilities updated. 4927 * @param nc the new network capabilities. 4928 */ updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc)4929 private void updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc) { 4930 NetworkCapabilities newNc = mixInCapabilities(nai, nc); 4931 4932 if (Objects.equals(nai.networkCapabilities, newNc)) return; 4933 4934 final String oldPermission = getNetworkPermission(nai.networkCapabilities); 4935 final String newPermission = getNetworkPermission(newNc); 4936 if (!Objects.equals(oldPermission, newPermission) && nai.created && !nai.isVPN()) { 4937 try { 4938 mNetd.setNetworkPermission(nai.network.netId, newPermission); 4939 } catch (RemoteException e) { 4940 loge("Exception in setNetworkPermission: " + e); 4941 } 4942 } 4943 4944 final NetworkCapabilities prevNc; 4945 synchronized (nai) { 4946 prevNc = nai.networkCapabilities; 4947 nai.networkCapabilities = newNc; 4948 } 4949 4950 updateUids(nai, prevNc, newNc); 4951 4952 if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) { 4953 // If the requestable capabilities haven't changed, and the score hasn't changed, then 4954 // the change we're processing can't affect any requests, it can only affect the listens 4955 // on this network. We might have been called by rematchNetworkAndRequests when a 4956 // network changed foreground state. 4957 processListenRequests(nai, true); 4958 } else { 4959 // If the requestable capabilities have changed or the score changed, we can't have been 4960 // called by rematchNetworkAndRequests, so it's safe to start a rematch. 4961 rematchAllNetworksAndRequests(nai, oldScore); 4962 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 4963 } 4964 4965 // Report changes that are interesting for network statistics tracking. 4966 if (prevNc != null) { 4967 final boolean meteredChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_METERED) != 4968 newNc.hasCapability(NET_CAPABILITY_NOT_METERED); 4969 final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) != 4970 newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING); 4971 if (meteredChanged || roamingChanged) { 4972 notifyIfacesChangedForNetworkStats(); 4973 } 4974 } 4975 4976 if (!newNc.hasTransport(TRANSPORT_VPN)) { 4977 // Tell VPNs about updated capabilities, since they may need to 4978 // bubble those changes through. 4979 updateAllVpnsCapabilities(); 4980 } 4981 } 4982 updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)4983 private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, 4984 NetworkCapabilities newNc) { 4985 Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids(); 4986 Set<UidRange> newRanges = null == newNc ? null : newNc.getUids(); 4987 if (null == prevRanges) prevRanges = new ArraySet<>(); 4988 if (null == newRanges) newRanges = new ArraySet<>(); 4989 final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges); 4990 4991 prevRanges.removeAll(newRanges); 4992 newRanges.removeAll(prevRangesCopy); 4993 4994 try { 4995 if (!newRanges.isEmpty()) { 4996 final UidRange[] addedRangesArray = new UidRange[newRanges.size()]; 4997 newRanges.toArray(addedRangesArray); 4998 mNetd.addVpnUidRanges(nai.network.netId, addedRangesArray); 4999 } 5000 if (!prevRanges.isEmpty()) { 5001 final UidRange[] removedRangesArray = new UidRange[prevRanges.size()]; 5002 prevRanges.toArray(removedRangesArray); 5003 mNetd.removeVpnUidRanges(nai.network.netId, removedRangesArray); 5004 } 5005 } catch (Exception e) { 5006 // Never crash! 5007 loge("Exception in updateUids: " + e); 5008 } 5009 } 5010 handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp)5011 public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) { 5012 if (getNetworkAgentInfoForNetId(nai.network.netId) != nai) { 5013 // Ignore updates for disconnected networks 5014 return; 5015 } 5016 // newLp is already a defensive copy. 5017 newLp.ensureDirectlyConnectedRoutes(); 5018 if (VDBG) { 5019 log("Update of LinkProperties for " + nai.name() + 5020 "; created=" + nai.created + 5021 "; everConnected=" + nai.everConnected); 5022 } 5023 LinkProperties oldLp = nai.linkProperties; 5024 synchronized (nai) { 5025 nai.linkProperties = newLp; 5026 } 5027 if (nai.everConnected) { 5028 updateLinkProperties(nai, oldLp); 5029 } 5030 } 5031 sendUpdatedScoreToFactories(NetworkAgentInfo nai)5032 private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) { 5033 for (int i = 0; i < nai.numNetworkRequests(); i++) { 5034 NetworkRequest nr = nai.requestAt(i); 5035 // Don't send listening requests to factories. b/17393458 5036 if (nr.isListen()) continue; 5037 sendUpdatedScoreToFactories(nr, nai.getCurrentScore()); 5038 } 5039 } 5040 sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score)5041 private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) { 5042 if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString()); 5043 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { 5044 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0, 5045 networkRequest); 5046 } 5047 } 5048 sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType)5049 private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, 5050 int notificationType) { 5051 if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) { 5052 Intent intent = new Intent(); 5053 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network); 5054 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, nri.request); 5055 nri.mPendingIntentSent = true; 5056 sendIntent(nri.mPendingIntent, intent); 5057 } 5058 // else not handled 5059 } 5060 sendIntent(PendingIntent pendingIntent, Intent intent)5061 private void sendIntent(PendingIntent pendingIntent, Intent intent) { 5062 mPendingIntentWakeLock.acquire(); 5063 try { 5064 if (DBG) log("Sending " + pendingIntent); 5065 pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */); 5066 } catch (PendingIntent.CanceledException e) { 5067 if (DBG) log(pendingIntent + " was not sent, it had been canceled."); 5068 mPendingIntentWakeLock.release(); 5069 releasePendingNetworkRequest(pendingIntent); 5070 } 5071 // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished() 5072 } 5073 5074 @Override onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)5075 public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, 5076 String resultData, Bundle resultExtras) { 5077 if (DBG) log("Finished sending " + pendingIntent); 5078 mPendingIntentWakeLock.release(); 5079 // Release with a delay so the receiving client has an opportunity to put in its 5080 // own request. 5081 releasePendingNetworkRequestWithDelay(pendingIntent); 5082 } 5083 callCallbackForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType, int arg1)5084 private void callCallbackForRequest(NetworkRequestInfo nri, 5085 NetworkAgentInfo networkAgent, int notificationType, int arg1) { 5086 if (nri.messenger == null) { 5087 return; // Default request has no msgr 5088 } 5089 Bundle bundle = new Bundle(); 5090 // TODO: check if defensive copies of data is needed. 5091 putParcelable(bundle, new NetworkRequest(nri.request)); 5092 Message msg = Message.obtain(); 5093 if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) { 5094 putParcelable(bundle, networkAgent.network); 5095 } 5096 switch (notificationType) { 5097 case ConnectivityManager.CALLBACK_AVAILABLE: { 5098 putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities)); 5099 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties)); 5100 break; 5101 } 5102 case ConnectivityManager.CALLBACK_LOSING: { 5103 msg.arg1 = arg1; 5104 break; 5105 } 5106 case ConnectivityManager.CALLBACK_CAP_CHANGED: { 5107 // networkAgent can't be null as it has been accessed a few lines above. 5108 final NetworkCapabilities nc = networkCapabilitiesRestrictedForCallerPermissions( 5109 networkAgent.networkCapabilities, nri.mPid, nri.mUid); 5110 putParcelable(bundle, nc); 5111 break; 5112 } 5113 case ConnectivityManager.CALLBACK_IP_CHANGED: { 5114 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties)); 5115 break; 5116 } 5117 } 5118 msg.what = notificationType; 5119 msg.setData(bundle); 5120 try { 5121 if (VDBG) { 5122 String notification = ConnectivityManager.getCallbackName(notificationType); 5123 log("sending notification " + notification + " for " + nri.request); 5124 } 5125 nri.messenger.send(msg); 5126 } catch (RemoteException e) { 5127 // may occur naturally in the race of binder death. 5128 loge("RemoteException caught trying to send a callback msg for " + nri.request); 5129 } 5130 } 5131 putParcelable(Bundle bundle, T t)5132 private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) { 5133 bundle.putParcelable(t.getClass().getSimpleName(), t); 5134 } 5135 teardownUnneededNetwork(NetworkAgentInfo nai)5136 private void teardownUnneededNetwork(NetworkAgentInfo nai) { 5137 if (nai.numRequestNetworkRequests() != 0) { 5138 for (int i = 0; i < nai.numNetworkRequests(); i++) { 5139 NetworkRequest nr = nai.requestAt(i); 5140 // Ignore listening requests. 5141 if (nr.isListen()) continue; 5142 loge("Dead network still had at least " + nr); 5143 break; 5144 } 5145 } 5146 nai.asyncChannel.disconnect(); 5147 } 5148 handleLingerComplete(NetworkAgentInfo oldNetwork)5149 private void handleLingerComplete(NetworkAgentInfo oldNetwork) { 5150 if (oldNetwork == null) { 5151 loge("Unknown NetworkAgentInfo in handleLingerComplete"); 5152 return; 5153 } 5154 if (DBG) log("handleLingerComplete for " + oldNetwork.name()); 5155 5156 // If we get here it means that the last linger timeout for this network expired. So there 5157 // must be no other active linger timers, and we must stop lingering. 5158 oldNetwork.clearLingerState(); 5159 5160 if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) { 5161 // Tear the network down. 5162 teardownUnneededNetwork(oldNetwork); 5163 } else { 5164 // Put the network in the background. 5165 updateCapabilities(oldNetwork.getCurrentScore(), oldNetwork, 5166 oldNetwork.networkCapabilities); 5167 } 5168 } 5169 makeDefault(NetworkAgentInfo newNetwork)5170 private void makeDefault(NetworkAgentInfo newNetwork) { 5171 if (DBG) log("Switching to new default network: " + newNetwork); 5172 setupDataActivityTracking(newNetwork); 5173 try { 5174 mNetd.setDefaultNetId(newNetwork.network.netId); 5175 } catch (Exception e) { 5176 loge("Exception setting default network :" + e); 5177 } 5178 5179 notifyLockdownVpn(newNetwork); 5180 handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy()); 5181 updateTcpBufferSizes(newNetwork); 5182 mDnsManager.setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers()); 5183 notifyIfacesChangedForNetworkStats(); 5184 } 5185 processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged)5186 private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) { 5187 // For consistency with previous behaviour, send onLost callbacks before onAvailable. 5188 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 5189 NetworkRequest nr = nri.request; 5190 if (!nr.isListen()) continue; 5191 if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) { 5192 nai.removeRequest(nri.request.requestId); 5193 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0); 5194 } 5195 } 5196 5197 if (capabilitiesChanged) { 5198 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); 5199 } 5200 5201 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 5202 NetworkRequest nr = nri.request; 5203 if (!nr.isListen()) continue; 5204 if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) { 5205 nai.addRequest(nr); 5206 notifyNetworkAvailable(nai, nri); 5207 } 5208 } 5209 } 5210 5211 // Handles a network appearing or improving its score. 5212 // 5213 // - Evaluates all current NetworkRequests that can be 5214 // satisfied by newNetwork, and reassigns to newNetwork 5215 // any such requests for which newNetwork is the best. 5216 // 5217 // - Lingers any validated Networks that as a result are no longer 5218 // needed. A network is needed if it is the best network for 5219 // one or more NetworkRequests, or if it is a VPN. 5220 // 5221 // - Tears down newNetwork if it just became validated 5222 // but turns out to be unneeded. 5223 // 5224 // - If reapUnvalidatedNetworks==REAP, tears down unvalidated 5225 // networks that have no chance (i.e. even if validated) 5226 // of becoming the highest scoring network. 5227 // 5228 // NOTE: This function only adds NetworkRequests that "newNetwork" could satisfy, 5229 // it does not remove NetworkRequests that other Networks could better satisfy. 5230 // If you need to handle decreases in score, use {@link rematchAllNetworksAndRequests}. 5231 // This function should be used when possible instead of {@code rematchAllNetworksAndRequests} 5232 // as it performs better by a factor of the number of Networks. 5233 // 5234 // @param newNetwork is the network to be matched against NetworkRequests. 5235 // @param reapUnvalidatedNetworks indicates if an additional pass over all networks should be 5236 // performed to tear down unvalidated networks that have no chance (i.e. even if 5237 // validated) of becoming the highest scoring network. rematchNetworkAndRequests(NetworkAgentInfo newNetwork, ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now)5238 private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, 5239 ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) { 5240 if (!newNetwork.everConnected) return; 5241 boolean keep = newNetwork.isVPN(); 5242 boolean isNewDefault = false; 5243 NetworkAgentInfo oldDefaultNetwork = null; 5244 5245 final boolean wasBackgroundNetwork = newNetwork.isBackgroundNetwork(); 5246 final int score = newNetwork.getCurrentScore(); 5247 5248 if (VDBG) log("rematching " + newNetwork.name()); 5249 5250 // Find and migrate to this Network any NetworkRequests for 5251 // which this network is now the best. 5252 ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>(); 5253 ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<NetworkRequestInfo>(); 5254 NetworkCapabilities nc = newNetwork.networkCapabilities; 5255 if (VDBG) log(" network has: " + nc); 5256 for (NetworkRequestInfo nri : mNetworkRequests.values()) { 5257 // Process requests in the first pass and listens in the second pass. This allows us to 5258 // change a network's capabilities depending on which requests it has. This is only 5259 // correct if the change in capabilities doesn't affect whether the network satisfies 5260 // requests or not, and doesn't affect the network's score. 5261 if (nri.request.isListen()) continue; 5262 5263 final NetworkAgentInfo currentNetwork = getNetworkForRequest(nri.request.requestId); 5264 final boolean satisfies = newNetwork.satisfies(nri.request); 5265 if (newNetwork == currentNetwork && satisfies) { 5266 if (VDBG) { 5267 log("Network " + newNetwork.name() + " was already satisfying" + 5268 " request " + nri.request.requestId + ". No change."); 5269 } 5270 keep = true; 5271 continue; 5272 } 5273 5274 // check if it satisfies the NetworkCapabilities 5275 if (VDBG) log(" checking if request is satisfied: " + nri.request); 5276 if (satisfies) { 5277 // next check if it's better than any current network we're using for 5278 // this request 5279 if (VDBG) { 5280 log("currentScore = " + 5281 (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) + 5282 ", newScore = " + score); 5283 } 5284 if (currentNetwork == null || currentNetwork.getCurrentScore() < score) { 5285 if (VDBG) log("rematch for " + newNetwork.name()); 5286 if (currentNetwork != null) { 5287 if (VDBG) log(" accepting network in place of " + currentNetwork.name()); 5288 currentNetwork.removeRequest(nri.request.requestId); 5289 currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs); 5290 affectedNetworks.add(currentNetwork); 5291 } else { 5292 if (VDBG) log(" accepting network in place of null"); 5293 } 5294 newNetwork.unlingerRequest(nri.request); 5295 setNetworkForRequest(nri.request.requestId, newNetwork); 5296 if (!newNetwork.addRequest(nri.request)) { 5297 Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request); 5298 } 5299 addedRequests.add(nri); 5300 keep = true; 5301 // Tell NetworkFactories about the new score, so they can stop 5302 // trying to connect if they know they cannot match it. 5303 // TODO - this could get expensive if we have alot of requests for this 5304 // network. Think about if there is a way to reduce this. Push 5305 // netid->request mapping to each factory? 5306 sendUpdatedScoreToFactories(nri.request, score); 5307 if (isDefaultRequest(nri)) { 5308 isNewDefault = true; 5309 oldDefaultNetwork = currentNetwork; 5310 if (currentNetwork != null) { 5311 mLingerMonitor.noteLingerDefaultNetwork(currentNetwork, newNetwork); 5312 } 5313 } 5314 } 5315 } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) { 5316 // If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri", 5317 // mark it as no longer satisfying "nri". Because networks are processed by 5318 // rematchAllNetworksAndRequests() in descending score order, "currentNetwork" will 5319 // match "newNetwork" before this loop will encounter a "currentNetwork" with higher 5320 // score than "newNetwork" and where "currentNetwork" no longer satisfies "nri". 5321 // This means this code doesn't have to handle the case where "currentNetwork" no 5322 // longer satisfies "nri" when "currentNetwork" does not equal "newNetwork". 5323 if (DBG) { 5324 log("Network " + newNetwork.name() + " stopped satisfying" + 5325 " request " + nri.request.requestId); 5326 } 5327 newNetwork.removeRequest(nri.request.requestId); 5328 if (currentNetwork == newNetwork) { 5329 clearNetworkForRequest(nri.request.requestId); 5330 sendUpdatedScoreToFactories(nri.request, 0); 5331 } else { 5332 Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " + 5333 newNetwork.name() + 5334 " without updating mNetworkForRequestId or factories!"); 5335 } 5336 // TODO: Technically, sending CALLBACK_LOST here is 5337 // incorrect if there is a replacement network currently 5338 // connected that can satisfy nri, which is a request 5339 // (not a listen). However, the only capability that can both 5340 // a) be requested and b) change is NET_CAPABILITY_TRUSTED, 5341 // so this code is only incorrect for a network that loses 5342 // the TRUSTED capability, which is a rare case. 5343 callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0); 5344 } 5345 } 5346 if (isNewDefault) { 5347 // Notify system services that this network is up. 5348 makeDefault(newNetwork); 5349 // Log 0 -> X and Y -> X default network transitions, where X is the new default. 5350 metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent( 5351 now, newNetwork, oldDefaultNetwork); 5352 // Have a new default network, release the transition wakelock in 5353 scheduleReleaseNetworkTransitionWakelock(); 5354 } 5355 5356 if (!newNetwork.networkCapabilities.equalRequestableCapabilities(nc)) { 5357 Slog.wtf(TAG, String.format( 5358 "BUG: %s changed requestable capabilities during rematch: %s -> %s", 5359 newNetwork.name(), nc, newNetwork.networkCapabilities)); 5360 } 5361 if (newNetwork.getCurrentScore() != score) { 5362 Slog.wtf(TAG, String.format( 5363 "BUG: %s changed score during rematch: %d -> %d", 5364 newNetwork.name(), score, newNetwork.getCurrentScore())); 5365 } 5366 5367 // Second pass: process all listens. 5368 if (wasBackgroundNetwork != newNetwork.isBackgroundNetwork()) { 5369 // If the network went from background to foreground or vice versa, we need to update 5370 // its foreground state. It is safe to do this after rematching the requests because 5371 // NET_CAPABILITY_FOREGROUND does not affect requests, as is not a requestable 5372 // capability and does not affect the network's score (see the Slog.wtf call above). 5373 updateCapabilities(score, newNetwork, newNetwork.networkCapabilities); 5374 } else { 5375 processListenRequests(newNetwork, false); 5376 } 5377 5378 // do this after the default net is switched, but 5379 // before LegacyTypeTracker sends legacy broadcasts 5380 for (NetworkRequestInfo nri : addedRequests) notifyNetworkAvailable(newNetwork, nri); 5381 5382 // Linger any networks that are no longer needed. This should be done after sending the 5383 // available callback for newNetwork. 5384 for (NetworkAgentInfo nai : affectedNetworks) { 5385 updateLingerState(nai, now); 5386 } 5387 // Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it 5388 // does not need to be done in any particular order. 5389 updateLingerState(newNetwork, now); 5390 5391 if (isNewDefault) { 5392 // Maintain the illusion: since the legacy API only 5393 // understands one network at a time, we must pretend 5394 // that the current default network disconnected before 5395 // the new one connected. 5396 if (oldDefaultNetwork != null) { 5397 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), 5398 oldDefaultNetwork, true); 5399 } 5400 mDefaultInetConditionPublished = newNetwork.lastValidated ? 100 : 0; 5401 mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork); 5402 notifyLockdownVpn(newNetwork); 5403 } 5404 5405 if (keep) { 5406 // Notify battery stats service about this network, both the normal 5407 // interface and any stacked links. 5408 // TODO: Avoid redoing this; this must only be done once when a network comes online. 5409 try { 5410 final IBatteryStats bs = BatteryStatsService.getService(); 5411 final int type = newNetwork.networkInfo.getType(); 5412 5413 final String baseIface = newNetwork.linkProperties.getInterfaceName(); 5414 bs.noteNetworkInterfaceType(baseIface, type); 5415 for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) { 5416 final String stackedIface = stacked.getInterfaceName(); 5417 bs.noteNetworkInterfaceType(stackedIface, type); 5418 } 5419 } catch (RemoteException ignored) { 5420 } 5421 5422 // This has to happen after the notifyNetworkCallbacks as that tickles each 5423 // ConnectivityManager instance so that legacy requests correctly bind dns 5424 // requests to this network. The legacy users are listening for this bcast 5425 // and will generally do a dns request so they can ensureRouteToHost and if 5426 // they do that before the callbacks happen they'll use the default network. 5427 // 5428 // TODO: Is there still a race here? We send the broadcast 5429 // after sending the callback, but if the app can receive the 5430 // broadcast before the callback, it might still break. 5431 // 5432 // This *does* introduce a race where if the user uses the new api 5433 // (notification callbacks) and then uses the old api (getNetworkInfo(type)) 5434 // they may get old info. Reverse this after the old startUsing api is removed. 5435 // This is on top of the multiple intent sequencing referenced in the todo above. 5436 for (int i = 0; i < newNetwork.numNetworkRequests(); i++) { 5437 NetworkRequest nr = newNetwork.requestAt(i); 5438 if (nr.legacyType != TYPE_NONE && nr.isRequest()) { 5439 // legacy type tracker filters out repeat adds 5440 mLegacyTypeTracker.add(nr.legacyType, newNetwork); 5441 } 5442 } 5443 5444 // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above, 5445 // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest 5446 // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the 5447 // newNetwork to the tracker explicitly (it's a no-op if it has already been added). 5448 if (newNetwork.isVPN()) { 5449 mLegacyTypeTracker.add(TYPE_VPN, newNetwork); 5450 } 5451 } 5452 if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) { 5453 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 5454 if (unneeded(nai, UnneededFor.TEARDOWN)) { 5455 if (nai.getLingerExpiry() > 0) { 5456 // This network has active linger timers and no requests, but is not 5457 // lingering. Linger it. 5458 // 5459 // One way (the only way?) this can happen if this network is unvalidated 5460 // and became unneeded due to another network improving its score to the 5461 // point where this network will no longer be able to satisfy any requests 5462 // even if it validates. 5463 updateLingerState(nai, now); 5464 } else { 5465 if (DBG) log("Reaping " + nai.name()); 5466 teardownUnneededNetwork(nai); 5467 } 5468 } 5469 } 5470 } 5471 } 5472 5473 /** 5474 * Attempt to rematch all Networks with NetworkRequests. This may result in Networks 5475 * being disconnected. 5476 * @param changed If only one Network's score or capabilities have been modified since the last 5477 * time this function was called, pass this Network in this argument, otherwise pass 5478 * null. 5479 * @param oldScore If only one Network has been changed but its NetworkCapabilities have not 5480 * changed, pass in the Network's score (from getCurrentScore()) prior to the change via 5481 * this argument, otherwise pass {@code changed.getCurrentScore()} or 0 if 5482 * {@code changed} is {@code null}. This is because NetworkCapabilities influence a 5483 * network's score. 5484 */ rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore)5485 private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) { 5486 // TODO: This may get slow. The "changed" parameter is provided for future optimization 5487 // to avoid the slowness. It is not simply enough to process just "changed", for 5488 // example in the case where "changed"'s score decreases and another network should begin 5489 // satifying a NetworkRequest that "changed" currently satisfies. 5490 5491 // Optimization: Only reprocess "changed" if its score improved. This is safe because it 5492 // can only add more NetworkRequests satisfied by "changed", and this is exactly what 5493 // rematchNetworkAndRequests() handles. 5494 final long now = SystemClock.elapsedRealtime(); 5495 if (changed != null && oldScore < changed.getCurrentScore()) { 5496 rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now); 5497 } else { 5498 final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray( 5499 new NetworkAgentInfo[mNetworkAgentInfos.size()]); 5500 // Rematch higher scoring networks first to prevent requests first matching a lower 5501 // scoring network and then a higher scoring network, which could produce multiple 5502 // callbacks and inadvertently unlinger networks. 5503 Arrays.sort(nais); 5504 for (NetworkAgentInfo nai : nais) { 5505 rematchNetworkAndRequests(nai, 5506 // Only reap the last time through the loop. Reaping before all rematching 5507 // is complete could incorrectly teardown a network that hasn't yet been 5508 // rematched. 5509 (nai != nais[nais.length-1]) ? ReapUnvalidatedNetworks.DONT_REAP 5510 : ReapUnvalidatedNetworks.REAP, 5511 now); 5512 } 5513 } 5514 } 5515 updateInetCondition(NetworkAgentInfo nai)5516 private void updateInetCondition(NetworkAgentInfo nai) { 5517 // Don't bother updating until we've graduated to validated at least once. 5518 if (!nai.everValidated) return; 5519 // For now only update icons for default connection. 5520 // TODO: Update WiFi and cellular icons separately. b/17237507 5521 if (!isDefaultNetwork(nai)) return; 5522 5523 int newInetCondition = nai.lastValidated ? 100 : 0; 5524 // Don't repeat publish. 5525 if (newInetCondition == mDefaultInetConditionPublished) return; 5526 5527 mDefaultInetConditionPublished = newInetCondition; 5528 sendInetConditionBroadcast(nai.networkInfo); 5529 } 5530 notifyLockdownVpn(NetworkAgentInfo nai)5531 private void notifyLockdownVpn(NetworkAgentInfo nai) { 5532 synchronized (mVpns) { 5533 if (mLockdownTracker != null) { 5534 if (nai != null && nai.isVPN()) { 5535 mLockdownTracker.onVpnStateChanged(nai.networkInfo); 5536 } else { 5537 mLockdownTracker.onNetworkInfoChanged(); 5538 } 5539 } 5540 } 5541 } 5542 updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo)5543 private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) { 5544 final NetworkInfo.State state = newInfo.getState(); 5545 NetworkInfo oldInfo = null; 5546 final int oldScore = networkAgent.getCurrentScore(); 5547 synchronized (networkAgent) { 5548 oldInfo = networkAgent.networkInfo; 5549 networkAgent.networkInfo = newInfo; 5550 } 5551 notifyLockdownVpn(networkAgent); 5552 5553 if (DBG) { 5554 log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " + 5555 (oldInfo == null ? "null" : oldInfo.getState()) + 5556 " to " + state); 5557 } 5558 5559 if (!networkAgent.created 5560 && (state == NetworkInfo.State.CONNECTED 5561 || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) { 5562 5563 // A network that has just connected has zero requests and is thus a foreground network. 5564 networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); 5565 5566 try { 5567 // This should never fail. Specifying an already in use NetID will cause failure. 5568 if (networkAgent.isVPN()) { 5569 mNetd.createVirtualNetwork(networkAgent.network.netId, 5570 !networkAgent.linkProperties.getDnsServers().isEmpty(), 5571 (networkAgent.networkMisc == null || 5572 !networkAgent.networkMisc.allowBypass)); 5573 } else { 5574 mNetd.createPhysicalNetwork(networkAgent.network.netId, 5575 getNetworkPermission(networkAgent.networkCapabilities)); 5576 } 5577 } catch (Exception e) { 5578 loge("Error creating network " + networkAgent.network.netId + ": " 5579 + e.getMessage()); 5580 return; 5581 } 5582 networkAgent.created = true; 5583 } 5584 5585 if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) { 5586 networkAgent.everConnected = true; 5587 5588 handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig()); 5589 updateLinkProperties(networkAgent, null); 5590 notifyIfacesChangedForNetworkStats(); 5591 5592 networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED); 5593 scheduleUnvalidatedPrompt(networkAgent); 5594 5595 if (networkAgent.isVPN()) { 5596 // Temporarily disable the default proxy (not global). 5597 synchronized (mProxyLock) { 5598 if (!mDefaultProxyDisabled) { 5599 mDefaultProxyDisabled = true; 5600 if (mGlobalProxy == null && mDefaultProxy != null) { 5601 sendProxyBroadcast(null); 5602 } 5603 } 5604 } 5605 // TODO: support proxy per network. 5606 } 5607 5608 // Whether a particular NetworkRequest listen should cause signal strength thresholds to 5609 // be communicated to a particular NetworkAgent depends only on the network's immutable, 5610 // capabilities, so it only needs to be done once on initial connect, not every time the 5611 // network's capabilities change. Note that we do this before rematching the network, 5612 // so we could decide to tear it down immediately afterwards. That's fine though - on 5613 // disconnection NetworkAgents should stop any signal strength monitoring they have been 5614 // doing. 5615 updateSignalStrengthThresholds(networkAgent, "CONNECT", null); 5616 5617 // Consider network even though it is not yet validated. 5618 final long now = SystemClock.elapsedRealtime(); 5619 rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP, now); 5620 5621 // This has to happen after matching the requests, because callbacks are just requests. 5622 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK); 5623 } else if (state == NetworkInfo.State.DISCONNECTED) { 5624 networkAgent.asyncChannel.disconnect(); 5625 if (networkAgent.isVPN()) { 5626 synchronized (mProxyLock) { 5627 if (mDefaultProxyDisabled) { 5628 mDefaultProxyDisabled = false; 5629 if (mGlobalProxy == null && mDefaultProxy != null) { 5630 sendProxyBroadcast(mDefaultProxy); 5631 } 5632 } 5633 } 5634 updateUids(networkAgent, networkAgent.networkCapabilities, null); 5635 } 5636 disconnectAndDestroyNetwork(networkAgent); 5637 } else if ((oldInfo != null && oldInfo.getState() == NetworkInfo.State.SUSPENDED) || 5638 state == NetworkInfo.State.SUSPENDED) { 5639 // going into or coming out of SUSPEND: rescore and notify 5640 if (networkAgent.getCurrentScore() != oldScore) { 5641 rematchAllNetworksAndRequests(networkAgent, oldScore); 5642 } 5643 updateCapabilities(networkAgent.getCurrentScore(), networkAgent, 5644 networkAgent.networkCapabilities); 5645 // TODO (b/73132094) : remove this call once the few users of onSuspended and 5646 // onResumed have been removed. 5647 notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ? 5648 ConnectivityManager.CALLBACK_SUSPENDED : 5649 ConnectivityManager.CALLBACK_RESUMED)); 5650 mLegacyTypeTracker.update(networkAgent); 5651 } 5652 } 5653 updateNetworkScore(NetworkAgentInfo nai, int score)5654 private void updateNetworkScore(NetworkAgentInfo nai, int score) { 5655 if (VDBG) log("updateNetworkScore for " + nai.name() + " to " + score); 5656 if (score < 0) { 5657 loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score + 5658 "). Bumping score to min of 0"); 5659 score = 0; 5660 } 5661 5662 final int oldScore = nai.getCurrentScore(); 5663 nai.setCurrentScore(score); 5664 5665 rematchAllNetworksAndRequests(nai, oldScore); 5666 5667 sendUpdatedScoreToFactories(nai); 5668 } 5669 5670 // Notify only this one new request of the current state. Transfer all the 5671 // current state by calling NetworkCapabilities and LinkProperties callbacks 5672 // so that callers can be guaranteed to have as close to atomicity in state 5673 // transfer as can be supported by this current API. notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri)5674 protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) { 5675 mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri); 5676 if (nri.mPendingIntent != null) { 5677 sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE); 5678 // Attempt no subsequent state pushes where intents are involved. 5679 return; 5680 } 5681 5682 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0); 5683 } 5684 sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type)5685 private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) { 5686 // The NetworkInfo we actually send out has no bearing on the real 5687 // state of affairs. For example, if the default connection is mobile, 5688 // and a request for HIPRI has just gone away, we need to pretend that 5689 // HIPRI has just disconnected. So we need to set the type to HIPRI and 5690 // the state to DISCONNECTED, even though the network is of type MOBILE 5691 // and is still connected. 5692 NetworkInfo info = new NetworkInfo(nai.networkInfo); 5693 info.setType(type); 5694 if (state != DetailedState.DISCONNECTED) { 5695 info.setDetailedState(state, null, info.getExtraInfo()); 5696 sendConnectedBroadcast(info); 5697 } else { 5698 info.setDetailedState(state, info.getReason(), info.getExtraInfo()); 5699 Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 5700 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 5701 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); 5702 if (info.isFailover()) { 5703 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 5704 nai.networkInfo.setFailover(false); 5705 } 5706 if (info.getReason() != null) { 5707 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 5708 } 5709 if (info.getExtraInfo() != null) { 5710 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo()); 5711 } 5712 NetworkAgentInfo newDefaultAgent = null; 5713 if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) { 5714 newDefaultAgent = getDefaultNetwork(); 5715 if (newDefaultAgent != null) { 5716 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, 5717 newDefaultAgent.networkInfo); 5718 } else { 5719 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); 5720 } 5721 } 5722 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, 5723 mDefaultInetConditionPublished); 5724 sendStickyBroadcast(intent); 5725 if (newDefaultAgent != null) { 5726 sendConnectedBroadcast(newDefaultAgent.networkInfo); 5727 } 5728 } 5729 } 5730 notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1)5731 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) { 5732 if (VDBG) { 5733 String notification = ConnectivityManager.getCallbackName(notifyType); 5734 log("notifyType " + notification + " for " + networkAgent.name()); 5735 } 5736 for (int i = 0; i < networkAgent.numNetworkRequests(); i++) { 5737 NetworkRequest nr = networkAgent.requestAt(i); 5738 NetworkRequestInfo nri = mNetworkRequests.get(nr); 5739 if (VDBG) log(" sending notification for " + nr); 5740 // TODO: if we're in the middle of a rematch, can we send a CAP_CHANGED callback for 5741 // a network that no longer satisfies the listen? 5742 if (nri.mPendingIntent == null) { 5743 callCallbackForRequest(nri, networkAgent, notifyType, arg1); 5744 } else { 5745 sendPendingIntentForRequest(nri, networkAgent, notifyType); 5746 } 5747 } 5748 } 5749 notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType)5750 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) { 5751 notifyNetworkCallbacks(networkAgent, notifyType, 0); 5752 } 5753 5754 /** 5755 * Returns the list of all interfaces that could be used by network traffic that does not 5756 * explicitly specify a network. This includes the default network, but also all VPNs that are 5757 * currently connected. 5758 * 5759 * Must be called on the handler thread. 5760 */ getDefaultNetworks()5761 private Network[] getDefaultNetworks() { 5762 ArrayList<Network> defaultNetworks = new ArrayList<>(); 5763 NetworkAgentInfo defaultNetwork = getDefaultNetwork(); 5764 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { 5765 if (nai.everConnected && (nai == defaultNetwork || nai.isVPN())) { 5766 defaultNetworks.add(nai.network); 5767 } 5768 } 5769 return defaultNetworks.toArray(new Network[0]); 5770 } 5771 5772 /** 5773 * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the 5774 * properties tracked by NetworkStatsService on an active iface has changed. 5775 */ notifyIfacesChangedForNetworkStats()5776 private void notifyIfacesChangedForNetworkStats() { 5777 try { 5778 mStatsService.forceUpdateIfaces(getDefaultNetworks()); 5779 } catch (Exception ignored) { 5780 } 5781 } 5782 5783 @Override addVpnAddress(String address, int prefixLength)5784 public boolean addVpnAddress(String address, int prefixLength) { 5785 int user = UserHandle.getUserId(Binder.getCallingUid()); 5786 synchronized (mVpns) { 5787 throwIfLockdownEnabled(); 5788 return mVpns.get(user).addAddress(address, prefixLength); 5789 } 5790 } 5791 5792 @Override removeVpnAddress(String address, int prefixLength)5793 public boolean removeVpnAddress(String address, int prefixLength) { 5794 int user = UserHandle.getUserId(Binder.getCallingUid()); 5795 synchronized (mVpns) { 5796 throwIfLockdownEnabled(); 5797 return mVpns.get(user).removeAddress(address, prefixLength); 5798 } 5799 } 5800 5801 @Override setUnderlyingNetworksForVpn(Network[] networks)5802 public boolean setUnderlyingNetworksForVpn(Network[] networks) { 5803 int user = UserHandle.getUserId(Binder.getCallingUid()); 5804 final boolean success; 5805 synchronized (mVpns) { 5806 throwIfLockdownEnabled(); 5807 success = mVpns.get(user).setUnderlyingNetworks(networks); 5808 } 5809 if (success) { 5810 mHandler.post(() -> notifyIfacesChangedForNetworkStats()); 5811 } 5812 return success; 5813 } 5814 5815 @Override getCaptivePortalServerUrl()5816 public String getCaptivePortalServerUrl() { 5817 enforceConnectivityInternalPermission(); 5818 return NetworkMonitor.getCaptivePortalServerHttpUrl(mContext); 5819 } 5820 5821 @Override startNattKeepalive(Network network, int intervalSeconds, Messenger messenger, IBinder binder, String srcAddr, int srcPort, String dstAddr)5822 public void startNattKeepalive(Network network, int intervalSeconds, Messenger messenger, 5823 IBinder binder, String srcAddr, int srcPort, String dstAddr) { 5824 enforceKeepalivePermission(); 5825 mKeepaliveTracker.startNattKeepalive( 5826 getNetworkAgentInfoForNetwork(network), 5827 intervalSeconds, messenger, binder, 5828 srcAddr, srcPort, dstAddr, ConnectivityManager.PacketKeepalive.NATT_PORT); 5829 } 5830 5831 @Override stopKeepalive(Network network, int slot)5832 public void stopKeepalive(Network network, int slot) { 5833 mHandler.sendMessage(mHandler.obtainMessage( 5834 NetworkAgent.CMD_STOP_PACKET_KEEPALIVE, slot, PacketKeepalive.SUCCESS, network)); 5835 } 5836 5837 @Override factoryReset()5838 public void factoryReset() { 5839 enforceConnectivityInternalPermission(); 5840 5841 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 5842 return; 5843 } 5844 5845 final int userId = UserHandle.getCallingUserId(); 5846 5847 // Turn airplane mode off 5848 setAirplaneMode(false); 5849 5850 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) { 5851 // Untether 5852 String pkgName = mContext.getOpPackageName(); 5853 for (String tether : getTetheredIfaces()) { 5854 untether(tether, pkgName); 5855 } 5856 } 5857 5858 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) { 5859 // Remove always-on package 5860 synchronized (mVpns) { 5861 final String alwaysOnPackage = getAlwaysOnVpnPackage(userId); 5862 if (alwaysOnPackage != null) { 5863 setAlwaysOnVpnPackage(userId, null, false); 5864 setVpnPackageAuthorization(alwaysOnPackage, userId, false); 5865 } 5866 5867 // Turn Always-on VPN off 5868 if (mLockdownEnabled && userId == UserHandle.USER_SYSTEM) { 5869 final long ident = Binder.clearCallingIdentity(); 5870 try { 5871 mKeyStore.delete(Credentials.LOCKDOWN_VPN); 5872 mLockdownEnabled = false; 5873 setLockdownTracker(null); 5874 } finally { 5875 Binder.restoreCallingIdentity(ident); 5876 } 5877 } 5878 5879 // Turn VPN off 5880 VpnConfig vpnConfig = getVpnConfig(userId); 5881 if (vpnConfig != null) { 5882 if (vpnConfig.legacy) { 5883 prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId); 5884 } else { 5885 // Prevent this app (packagename = vpnConfig.user) from initiating 5886 // VPN connections in the future without user intervention. 5887 setVpnPackageAuthorization(vpnConfig.user, userId, false); 5888 5889 prepareVpn(null, VpnConfig.LEGACY_VPN, userId); 5890 } 5891 } 5892 } 5893 } 5894 5895 Settings.Global.putString(mContext.getContentResolver(), 5896 Settings.Global.NETWORK_AVOID_BAD_WIFI, null); 5897 } 5898 5899 @Override getNetworkWatchlistConfigHash()5900 public byte[] getNetworkWatchlistConfigHash() { 5901 NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class); 5902 if (nwm == null) { 5903 loge("Unable to get NetworkWatchlistManager"); 5904 return null; 5905 } 5906 // Redirect it to network watchlist service to access watchlist file and calculate hash. 5907 return nwm.getWatchlistConfigHash(); 5908 } 5909 5910 @VisibleForTesting createNetworkMonitor(Context context, Handler handler, NetworkAgentInfo nai, NetworkRequest defaultRequest)5911 public NetworkMonitor createNetworkMonitor(Context context, Handler handler, 5912 NetworkAgentInfo nai, NetworkRequest defaultRequest) { 5913 return new NetworkMonitor(context, handler, nai, defaultRequest); 5914 } 5915 5916 @VisibleForTesting createMultinetworkPolicyTracker(Context c, Handler h, Runnable r)5917 MultinetworkPolicyTracker createMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { 5918 return new MultinetworkPolicyTracker(c, h, r); 5919 } 5920 5921 @VisibleForTesting makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj)5922 public WakeupMessage makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj) { 5923 return new WakeupMessage(c, h, s, cmd, 0, 0, obj); 5924 } 5925 5926 @VisibleForTesting hasService(String name)5927 public boolean hasService(String name) { 5928 return ServiceManager.checkService(name) != null; 5929 } 5930 5931 @VisibleForTesting metricsLogger()5932 protected IpConnectivityMetrics.Logger metricsLogger() { 5933 return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class), 5934 "no IpConnectivityMetrics service"); 5935 } 5936 logNetworkEvent(NetworkAgentInfo nai, int evtype)5937 private void logNetworkEvent(NetworkAgentInfo nai, int evtype) { 5938 int[] transports = nai.networkCapabilities.getTransportTypes(); 5939 mMetricsLog.log(nai.network.netId, transports, new NetworkEvent(evtype)); 5940 } 5941 toBool(int encodedBoolean)5942 private static boolean toBool(int encodedBoolean) { 5943 return encodedBoolean != 0; // Only 0 means false. 5944 } 5945 encodeBool(boolean b)5946 private static int encodeBool(boolean b) { 5947 return b ? 1 : 0; 5948 } 5949 5950 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)5951 public void onShellCommand(FileDescriptor in, FileDescriptor out, 5952 FileDescriptor err, String[] args, ShellCallback callback, 5953 ResultReceiver resultReceiver) { 5954 (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver); 5955 } 5956 5957 private class ShellCmd extends ShellCommand { 5958 5959 @Override onCommand(String cmd)5960 public int onCommand(String cmd) { 5961 if (cmd == null) { 5962 return handleDefaultCommands(cmd); 5963 } 5964 final PrintWriter pw = getOutPrintWriter(); 5965 try { 5966 switch (cmd) { 5967 case "airplane-mode": 5968 final String action = getNextArg(); 5969 if ("enable".equals(action)) { 5970 setAirplaneMode(true); 5971 return 0; 5972 } else if ("disable".equals(action)) { 5973 setAirplaneMode(false); 5974 return 0; 5975 } else if (action == null) { 5976 final ContentResolver cr = mContext.getContentResolver(); 5977 final int enabled = Settings.Global.getInt(cr, 5978 Settings.Global.AIRPLANE_MODE_ON); 5979 pw.println(enabled == 0 ? "disabled" : "enabled"); 5980 return 0; 5981 } else { 5982 onHelp(); 5983 return -1; 5984 } 5985 default: 5986 return handleDefaultCommands(cmd); 5987 } 5988 } catch (Exception e) { 5989 pw.println(e); 5990 } 5991 return -1; 5992 } 5993 5994 @Override onHelp()5995 public void onHelp() { 5996 PrintWriter pw = getOutPrintWriter(); 5997 pw.println("Connectivity service commands:"); 5998 pw.println(" help"); 5999 pw.println(" Print this help text."); 6000 pw.println(" airplane-mode [enable|disable]"); 6001 pw.println(" Turn airplane mode on or off."); 6002 pw.println(" airplane-mode"); 6003 pw.println(" Get airplane mode."); 6004 } 6005 } 6006 } 6007