Loading services/core/java/com/android/server/ConnectivityService.java +125 −103 Original line number Diff line number Diff line Loading @@ -150,7 +150,6 @@ import android.util.Log; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.util.Xml; Loading @@ -168,7 +167,6 @@ import com.android.internal.util.AsyncChannel; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; import com.android.internal.util.WakeupMessage; import com.android.internal.util.XmlUtils; import com.android.server.am.BatteryStatsService; import com.android.server.connectivity.AutodestructReference; Loading Loading @@ -305,7 +303,8 @@ public class ConnectivityService extends IConnectivityManager.Stub /** Flag indicating if background data is restricted. */ private boolean mRestrictBackground; final private Context mContext; private final Context mContext; private final Dependencies mDeps; // 0 is full bad, 100 is full good private int mDefaultInetConditionPublished = 0; Loading Loading @@ -586,11 +585,6 @@ public class ConnectivityService extends IConnectivityManager.Stub private NetworkNotificationManager mNotifier; private LingerMonitor mLingerMonitor; // sequence number for Networks; keep in sync with system/netd/NetworkController.cpp private static final int MIN_NET_ID = 100; // some reserved marks private static final int MAX_NET_ID = 65535 - 0x0400; // Top 1024 bits reserved by IpSecService private int mNextNetId = MIN_NET_ID; // sequence number of NetworkRequests private int mNextNetworkRequestId = 1; Loading Loading @@ -834,19 +828,113 @@ public class ConnectivityService extends IConnectivityManager.Stub } }; /** * Dependencies of ConnectivityService, for injection in tests. */ @VisibleForTesting public static class Dependencies { /** * Get system properties to use in ConnectivityService. */ public MockableSystemProperties getSystemProperties() { return new MockableSystemProperties(); } /** * Create a HandlerThread to use in ConnectivityService. */ public HandlerThread makeHandlerThread() { return new HandlerThread("ConnectivityServiceThread"); } /** * Get a reference to the NetworkStackClient. */ public NetworkStackClient getNetworkStack() { return NetworkStackClient.getInstance(); } /** * @see Tethering */ public Tethering makeTethering(@NonNull Context context, @NonNull INetworkManagementService nms, @NonNull INetworkStatsService statsService, @NonNull INetworkPolicyManager policyManager, @NonNull TetheringDependencies tetheringDeps) { return new Tethering(context, nms, statsService, policyManager, IoThread.get().getLooper(), getSystemProperties(), tetheringDeps); } /** * @see ProxyTracker */ public ProxyTracker makeProxyTracker(@NonNull Context context, @NonNull Handler connServiceHandler) { return new ProxyTracker(context, connServiceHandler, EVENT_PROXY_HAS_CHANGED); } /** * @see NetIdManager */ public NetIdManager makeNetIdManager() { return new NetIdManager(); } /** * @see NetworkUtils#queryUserAccess(int, int) */ public boolean queryUserAccess(int uid, int netId) { return NetworkUtils.queryUserAccess(uid, netId); } /** * @see MultinetworkPolicyTracker */ public MultinetworkPolicyTracker makeMultinetworkPolicyTracker( @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) { return new MultinetworkPolicyTracker(c, h, r); } /** * @see ServiceManager#checkService(String) */ public boolean hasService(@NonNull String name) { return ServiceManager.checkService(name) != null; } /** * @see IpConnectivityMetrics.Logger */ public IpConnectivityMetrics.Logger getMetricsLogger() { return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class), "no IpConnectivityMetrics service"); } /** * @see IpConnectivityMetrics */ public IIpConnectivityMetrics getIpConnectivityMetrics() { return IIpConnectivityMetrics.Stub.asInterface( ServiceManager.getService(IpConnectivityLog.SERVICE_NAME)); } } public ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager) { this(context, netManager, statsService, policyManager, getDnsResolver(), new IpConnectivityLog(), NetdService.getInstance()); this(context, netManager, statsService, policyManager, getDnsResolver(), new IpConnectivityLog(), NetdService.getInstance(), new Dependencies()); } @VisibleForTesting protected ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager, IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd) { IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps) { if (DBG) log("ConnectivityService starting up"); mSystemProperties = getSystemProperties(); mDeps = checkNotNull(deps, "missing Dependencies"); mSystemProperties = mDeps.getSystemProperties(); mNetIdManager = mDeps.makeNetIdManager(); mMetricsLog = logger; mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST); Loading @@ -863,7 +951,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mDefaultWifiRequest = createDefaultInternetRequestForTransport( NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST); mHandlerThread = new HandlerThread("ConnectivityServiceThread"); mHandlerThread = mDeps.makeHandlerThread(); mHandlerThread.start(); mHandler = new InternalHandler(mHandlerThread.getLooper()); mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); Loading @@ -881,7 +969,7 @@ public class ConnectivityService extends IConnectivityManager.Stub LocalServices.getService(NetworkPolicyManagerInternal.class), "missing NetworkPolicyManagerInternal"); mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver"); mProxyTracker = makeProxyTracker(); mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler); mNetd = netd; mKeyStore = KeyStore.getInstance(); Loading Loading @@ -949,7 +1037,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Do the same for Ethernet, since it's often not specified in the configs, although many // devices can use it via USB host adapters. if (mNetConfigs[TYPE_ETHERNET] == null && hasService(Context.ETHERNET_SERVICE)) { if (mNetConfigs[TYPE_ETHERNET] == null && mDeps.hasService(Context.ETHERNET_SERVICE)) { mLegacyTypeTracker.addSupportedType(TYPE_ETHERNET); mNetworksDefined++; } Loading @@ -969,7 +1057,8 @@ public class ConnectivityService extends IConnectivityManager.Stub mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mTethering = makeTethering(); mTethering = deps.makeTethering(mContext, mNMS, mStatsService, mPolicyManager, makeTetheringDependencies()); mPermissionMonitor = new PermissionMonitor(mContext, mNetd); Loading Loading @@ -1028,7 +1117,7 @@ public class ConnectivityService extends IConnectivityManager.Stub LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS); mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit); mMultinetworkPolicyTracker = createMultinetworkPolicyTracker( mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker( mContext, mHandler, () -> rematchForAvoidBadWifiUpdate()); mMultinetworkPolicyTracker.start(); Loading @@ -1038,10 +1127,8 @@ public class ConnectivityService extends IConnectivityManager.Stub registerPrivateDnsSettingsCallbacks(); } @VisibleForTesting protected Tethering makeTethering() { // TODO: Move other elements into @Overridden getters. final TetheringDependencies deps = new TetheringDependencies() { private TetheringDependencies makeTetheringDependencies() { return new TetheringDependencies() { @Override public boolean isTetheringSupported() { return ConnectivityService.this.isTetheringSupported(); Loading @@ -1051,14 +1138,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return mDefaultRequest; } }; return new Tethering(mContext, mNMS, mStatsService, mPolicyManager, IoThread.get().getLooper(), new MockableSystemProperties(), deps); } @VisibleForTesting protected ProxyTracker makeProxyTracker() { return new ProxyTracker(mContext, mHandler, EVENT_PROXY_HAS_CHANGED); } private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { Loading Loading @@ -1150,22 +1229,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return mNextNetworkRequestId++; } @VisibleForTesting protected int reserveNetId() { synchronized (mNetworkForNetId) { for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) { int netId = mNextNetId; if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID; // Make sure NetID unused. http://b/16815182 if (!mNetIdInUse.get(netId)) { mNetIdInUse.put(netId, true); return netId; } } } throw new IllegalStateException("No free netIds"); } private NetworkState getFilteredNetworkState(int networkType, int uid) { if (mLegacyTypeTracker.isTypeSupported(networkType)) { final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); Loading Loading @@ -1797,11 +1860,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } }; @VisibleForTesting protected void registerNetdEventCallback() { final IIpConnectivityMetrics ipConnectivityMetrics = IIpConnectivityMetrics.Stub.asInterface( ServiceManager.getService(IpConnectivityLog.SERVICE_NAME)); private void registerNetdEventCallback() { final IIpConnectivityMetrics ipConnectivityMetrics = mDeps.getIpConnectivityMetrics(); if (ipConnectivityMetrics == null) { Slog.wtf(TAG, "Missing IIpConnectivityMetrics"); return; Loading Loading @@ -2237,12 +2297,6 @@ public class ConnectivityService extends IConnectivityManager.Stub protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; private static final String DEFAULT_TCP_RWND_KEY = "net.tcp.default_init_rwnd"; // Overridden for testing purposes to avoid writing to SystemProperties. @VisibleForTesting protected MockableSystemProperties getSystemProperties() { return new MockableSystemProperties(); } private void updateTcpBufferSizes(String tcpBufferSizes) { String[] values = null; if (tcpBufferSizes != null) { Loading Loading @@ -2632,7 +2686,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } if (valid != nai.lastValidated) { if (wasDefault) { metricsLogger().defaultNetworkMetrics().logDefaultNetworkValidity( mDeps.getMetricsLogger() .defaultNetworkMetrics().logDefaultNetworkValidity( SystemClock.elapsedRealtime(), valid); } final int oldScore = nai.getCurrentScore(); Loading Loading @@ -2968,8 +3023,8 @@ public class ConnectivityService extends IConnectivityManager.Stub final boolean wasDefault = isDefaultNetwork(nai); synchronized (mNetworkForNetId) { mNetworkForNetId.remove(nai.network.netId); mNetIdInUse.delete(nai.network.netId); } mNetIdManager.releaseNetId(nai.network.netId); // Just in case. mLegacyTypeTracker.remove(nai, wasDefault); } Loading Loading @@ -3016,7 +3071,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence // whose timestamps tell how long it takes to recover a default network. long now = SystemClock.elapsedRealtime(); metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai); mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai); } notifyIfacesChangedForNetworkStats(); // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied Loading Loading @@ -3070,9 +3125,7 @@ public class ConnectivityService extends IConnectivityManager.Stub destroyNativeNetwork(nai); mDnsManager.removeNetwork(nai.network); } synchronized (mNetworkForNetId) { mNetIdInUse.delete(nai.network.netId); } mNetIdManager.releaseNetId(nai.network.netId); } private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) { Loading Loading @@ -4156,7 +4209,7 @@ public class ConnectivityService extends IConnectivityManager.Stub return null; } return getLinkPropertiesProxyInfo(activeNetwork); } else if (queryUserAccess(Binder.getCallingUid(), network.netId)) { } else if (mDeps.queryUserAccess(Binder.getCallingUid(), network.netId)) { // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which // caller may not have. return getLinkPropertiesProxyInfo(network); Loading @@ -4165,10 +4218,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return null; } @VisibleForTesting protected boolean queryUserAccess(int uid, int netId) { return NetworkUtils.queryUserAccess(uid, netId); } private ProxyInfo getLinkPropertiesProxyInfo(Network network) { final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); Loading Loading @@ -4761,7 +4810,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final long ident = Binder.clearCallingIdentity(); try { // Concatenate the range of types onto the range of NetIDs. int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); mNotifier.setProvNotificationVisible(visible, id, action); } finally { Binder.restoreCallingIdentity(ident); Loading Loading @@ -5372,10 +5421,9 @@ public class ConnectivityService extends IConnectivityManager.Stub @GuardedBy("mNetworkForNetId") private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId. // An entry is first added to mNetIdInUse, prior to mNetworkForNetId, so // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so // there may not be a strict 1:1 correlation between the two. @GuardedBy("mNetworkForNetId") private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray(); private final NetIdManager mNetIdManager; // NetworkAgentInfo keyed off its connecting messenger // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays Loading Loading @@ -5477,9 +5525,9 @@ public class ConnectivityService extends IConnectivityManager.Stub // satisfies mDefaultRequest. final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver, mNMS, factorySerialNumber); new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver, mNMS, factorySerialNumber); // Make sure the network capabilities reflect what the agent info says. nai.setNetworkCapabilities(mixInCapabilities(nai, nc)); final String extraInfo = networkInfo.getExtraInfo(); Loading @@ -5488,7 +5536,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) log("registerNetworkAgent " + nai); final long token = Binder.clearCallingIdentity(); try { getNetworkStack().makeNetworkMonitor( mDeps.getNetworkStack().makeNetworkMonitor( nai.network, name, new NetworkMonitorCallbacks(nai)); } finally { Binder.restoreCallingIdentity(token); Loading @@ -5500,11 +5548,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return nai.network.netId; } @VisibleForTesting protected NetworkStackClient getNetworkStack() { return NetworkStackClient.getInstance(); } private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { nai.onNetworkMonitorCreated(networkMonitor); if (VDBG) log("Got NetworkAgent Messenger"); Loading Loading @@ -6313,7 +6356,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Notify system services that this network is up. makeDefault(newNetwork); // Log 0 -> X and Y -> X default network transitions, where X is the new default. metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent( mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent( now, newNetwork, oldDefaultNetwork); // Have a new default network, release the transition wakelock in scheduleReleaseNetworkTransitionWakelock(); Loading Loading @@ -6990,27 +7033,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return nwm.getWatchlistConfigHash(); } @VisibleForTesting MultinetworkPolicyTracker createMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { return new MultinetworkPolicyTracker(c, h, r); } @VisibleForTesting public WakeupMessage makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj) { return new WakeupMessage(c, h, s, cmd, 0, 0, obj); } @VisibleForTesting public boolean hasService(String name) { return ServiceManager.checkService(name) != null; } @VisibleForTesting protected IpConnectivityMetrics.Logger metricsLogger() { return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class), "no IpConnectivityMetrics service"); } private void logNetworkEvent(NetworkAgentInfo nai, int evtype) { int[] transports = nai.networkCapabilities.getTransportTypes(); mMetricsLog.log(nai.network.netId, transports, new NetworkEvent(evtype)); Loading services/core/java/com/android/server/IpSecService.java +2 −2 Original line number Diff line number Diff line Loading @@ -750,10 +750,10 @@ public class IpSecService extends IIpSecService.Stub { } } // These values have been reserved in ConnectivityService // These values have been reserved in NetIdManager @VisibleForTesting static final int TUN_INTF_NETID_START = 0xFC00; @VisibleForTesting static final int TUN_INTF_NETID_RANGE = 0x0400; public static final int TUN_INTF_NETID_RANGE = 0x0400; private final SparseBooleanArray mTunnelNetIds = new SparseBooleanArray(); private int mNextTunnelNetIdIndex = 0; Loading services/core/java/com/android/server/NetIdManager.java 0 → 100644 +76 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import android.annotation.NonNull; import android.util.SparseBooleanArray; import com.android.internal.annotations.GuardedBy; /** * Class used to reserve and release net IDs. * * <p>Instances of this class are thread-safe. */ public class NetIdManager { // Sequence number for Networks; keep in sync with system/netd/NetworkController.cpp public static final int MIN_NET_ID = 100; // some reserved marks // Top IDs reserved by IpSecService public static final int MAX_NET_ID = 65535 - IpSecService.TUN_INTF_NETID_RANGE; @GuardedBy("mNetIdInUse") private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray(); @GuardedBy("mNetIdInUse") private int mLastNetId = MIN_NET_ID - 1; /** * Get the first netId that follows the provided lastId and is available. */ private static int getNextAvailableNetIdLocked( int lastId, @NonNull SparseBooleanArray netIdInUse) { int netId = lastId; for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) { netId = netId < MAX_NET_ID ? netId + 1 : MIN_NET_ID; if (!netIdInUse.get(netId)) { return netId; } } throw new IllegalStateException("No free netIds"); } /** * Reserve a new ID for a network. */ public int reserveNetId() { synchronized (mNetIdInUse) { mLastNetId = getNextAvailableNetIdLocked(mLastNetId, mNetIdInUse); // Make sure NetID unused. http://b/16815182 mNetIdInUse.put(mLastNetId, true); return mLastNetId; } } /** * Clear a previously reserved ID for a network. */ public void releaseNetId(int id) { synchronized (mNetIdInUse) { mNetIdInUse.delete(id); } } } services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +5 −3 Original line number Diff line number Diff line Loading @@ -580,10 +580,12 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { } if (newExpiry > 0) { mLingerMessage = mConnService.makeWakeupMessage( mLingerMessage = new WakeupMessage( mContext, mHandler, "NETWORK_LINGER_COMPLETE." + network.netId, EVENT_NETWORK_LINGER_COMPLETE, this); "NETWORK_LINGER_COMPLETE." + network.netId /* cmdName */, EVENT_NETWORK_LINGER_COMPLETE /* cmd */, 0 /* arg1 (unused) */, 0 /* arg2 (unused) */, this /* obj (NetworkAgentInfo) */); mLingerMessage.schedule(newExpiry); } Loading tests/net/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ android_test { "androidx.test.rules", "FrameworksNetCommonTests", "frameworks-base-testutils", "frameworks-net-integration-testutils", "framework-protos", "mockito-target-minus-junit4", "net-tests-utils", Loading Loading
services/core/java/com/android/server/ConnectivityService.java +125 −103 Original line number Diff line number Diff line Loading @@ -150,7 +150,6 @@ import android.util.Log; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.util.Xml; Loading @@ -168,7 +167,6 @@ import com.android.internal.util.AsyncChannel; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; import com.android.internal.util.WakeupMessage; import com.android.internal.util.XmlUtils; import com.android.server.am.BatteryStatsService; import com.android.server.connectivity.AutodestructReference; Loading Loading @@ -305,7 +303,8 @@ public class ConnectivityService extends IConnectivityManager.Stub /** Flag indicating if background data is restricted. */ private boolean mRestrictBackground; final private Context mContext; private final Context mContext; private final Dependencies mDeps; // 0 is full bad, 100 is full good private int mDefaultInetConditionPublished = 0; Loading Loading @@ -586,11 +585,6 @@ public class ConnectivityService extends IConnectivityManager.Stub private NetworkNotificationManager mNotifier; private LingerMonitor mLingerMonitor; // sequence number for Networks; keep in sync with system/netd/NetworkController.cpp private static final int MIN_NET_ID = 100; // some reserved marks private static final int MAX_NET_ID = 65535 - 0x0400; // Top 1024 bits reserved by IpSecService private int mNextNetId = MIN_NET_ID; // sequence number of NetworkRequests private int mNextNetworkRequestId = 1; Loading Loading @@ -834,19 +828,113 @@ public class ConnectivityService extends IConnectivityManager.Stub } }; /** * Dependencies of ConnectivityService, for injection in tests. */ @VisibleForTesting public static class Dependencies { /** * Get system properties to use in ConnectivityService. */ public MockableSystemProperties getSystemProperties() { return new MockableSystemProperties(); } /** * Create a HandlerThread to use in ConnectivityService. */ public HandlerThread makeHandlerThread() { return new HandlerThread("ConnectivityServiceThread"); } /** * Get a reference to the NetworkStackClient. */ public NetworkStackClient getNetworkStack() { return NetworkStackClient.getInstance(); } /** * @see Tethering */ public Tethering makeTethering(@NonNull Context context, @NonNull INetworkManagementService nms, @NonNull INetworkStatsService statsService, @NonNull INetworkPolicyManager policyManager, @NonNull TetheringDependencies tetheringDeps) { return new Tethering(context, nms, statsService, policyManager, IoThread.get().getLooper(), getSystemProperties(), tetheringDeps); } /** * @see ProxyTracker */ public ProxyTracker makeProxyTracker(@NonNull Context context, @NonNull Handler connServiceHandler) { return new ProxyTracker(context, connServiceHandler, EVENT_PROXY_HAS_CHANGED); } /** * @see NetIdManager */ public NetIdManager makeNetIdManager() { return new NetIdManager(); } /** * @see NetworkUtils#queryUserAccess(int, int) */ public boolean queryUserAccess(int uid, int netId) { return NetworkUtils.queryUserAccess(uid, netId); } /** * @see MultinetworkPolicyTracker */ public MultinetworkPolicyTracker makeMultinetworkPolicyTracker( @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) { return new MultinetworkPolicyTracker(c, h, r); } /** * @see ServiceManager#checkService(String) */ public boolean hasService(@NonNull String name) { return ServiceManager.checkService(name) != null; } /** * @see IpConnectivityMetrics.Logger */ public IpConnectivityMetrics.Logger getMetricsLogger() { return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class), "no IpConnectivityMetrics service"); } /** * @see IpConnectivityMetrics */ public IIpConnectivityMetrics getIpConnectivityMetrics() { return IIpConnectivityMetrics.Stub.asInterface( ServiceManager.getService(IpConnectivityLog.SERVICE_NAME)); } } public ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager) { this(context, netManager, statsService, policyManager, getDnsResolver(), new IpConnectivityLog(), NetdService.getInstance()); this(context, netManager, statsService, policyManager, getDnsResolver(), new IpConnectivityLog(), NetdService.getInstance(), new Dependencies()); } @VisibleForTesting protected ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager, IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd) { IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps) { if (DBG) log("ConnectivityService starting up"); mSystemProperties = getSystemProperties(); mDeps = checkNotNull(deps, "missing Dependencies"); mSystemProperties = mDeps.getSystemProperties(); mNetIdManager = mDeps.makeNetIdManager(); mMetricsLog = logger; mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST); Loading @@ -863,7 +951,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mDefaultWifiRequest = createDefaultInternetRequestForTransport( NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST); mHandlerThread = new HandlerThread("ConnectivityServiceThread"); mHandlerThread = mDeps.makeHandlerThread(); mHandlerThread.start(); mHandler = new InternalHandler(mHandlerThread.getLooper()); mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); Loading @@ -881,7 +969,7 @@ public class ConnectivityService extends IConnectivityManager.Stub LocalServices.getService(NetworkPolicyManagerInternal.class), "missing NetworkPolicyManagerInternal"); mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver"); mProxyTracker = makeProxyTracker(); mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler); mNetd = netd; mKeyStore = KeyStore.getInstance(); Loading Loading @@ -949,7 +1037,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Do the same for Ethernet, since it's often not specified in the configs, although many // devices can use it via USB host adapters. if (mNetConfigs[TYPE_ETHERNET] == null && hasService(Context.ETHERNET_SERVICE)) { if (mNetConfigs[TYPE_ETHERNET] == null && mDeps.hasService(Context.ETHERNET_SERVICE)) { mLegacyTypeTracker.addSupportedType(TYPE_ETHERNET); mNetworksDefined++; } Loading @@ -969,7 +1057,8 @@ public class ConnectivityService extends IConnectivityManager.Stub mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mTethering = makeTethering(); mTethering = deps.makeTethering(mContext, mNMS, mStatsService, mPolicyManager, makeTetheringDependencies()); mPermissionMonitor = new PermissionMonitor(mContext, mNetd); Loading Loading @@ -1028,7 +1117,7 @@ public class ConnectivityService extends IConnectivityManager.Stub LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS); mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit); mMultinetworkPolicyTracker = createMultinetworkPolicyTracker( mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker( mContext, mHandler, () -> rematchForAvoidBadWifiUpdate()); mMultinetworkPolicyTracker.start(); Loading @@ -1038,10 +1127,8 @@ public class ConnectivityService extends IConnectivityManager.Stub registerPrivateDnsSettingsCallbacks(); } @VisibleForTesting protected Tethering makeTethering() { // TODO: Move other elements into @Overridden getters. final TetheringDependencies deps = new TetheringDependencies() { private TetheringDependencies makeTetheringDependencies() { return new TetheringDependencies() { @Override public boolean isTetheringSupported() { return ConnectivityService.this.isTetheringSupported(); Loading @@ -1051,14 +1138,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return mDefaultRequest; } }; return new Tethering(mContext, mNMS, mStatsService, mPolicyManager, IoThread.get().getLooper(), new MockableSystemProperties(), deps); } @VisibleForTesting protected ProxyTracker makeProxyTracker() { return new ProxyTracker(mContext, mHandler, EVENT_PROXY_HAS_CHANGED); } private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { Loading Loading @@ -1150,22 +1229,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return mNextNetworkRequestId++; } @VisibleForTesting protected int reserveNetId() { synchronized (mNetworkForNetId) { for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) { int netId = mNextNetId; if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID; // Make sure NetID unused. http://b/16815182 if (!mNetIdInUse.get(netId)) { mNetIdInUse.put(netId, true); return netId; } } } throw new IllegalStateException("No free netIds"); } private NetworkState getFilteredNetworkState(int networkType, int uid) { if (mLegacyTypeTracker.isTypeSupported(networkType)) { final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); Loading Loading @@ -1797,11 +1860,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } }; @VisibleForTesting protected void registerNetdEventCallback() { final IIpConnectivityMetrics ipConnectivityMetrics = IIpConnectivityMetrics.Stub.asInterface( ServiceManager.getService(IpConnectivityLog.SERVICE_NAME)); private void registerNetdEventCallback() { final IIpConnectivityMetrics ipConnectivityMetrics = mDeps.getIpConnectivityMetrics(); if (ipConnectivityMetrics == null) { Slog.wtf(TAG, "Missing IIpConnectivityMetrics"); return; Loading Loading @@ -2237,12 +2297,6 @@ public class ConnectivityService extends IConnectivityManager.Stub protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; private static final String DEFAULT_TCP_RWND_KEY = "net.tcp.default_init_rwnd"; // Overridden for testing purposes to avoid writing to SystemProperties. @VisibleForTesting protected MockableSystemProperties getSystemProperties() { return new MockableSystemProperties(); } private void updateTcpBufferSizes(String tcpBufferSizes) { String[] values = null; if (tcpBufferSizes != null) { Loading Loading @@ -2632,7 +2686,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } if (valid != nai.lastValidated) { if (wasDefault) { metricsLogger().defaultNetworkMetrics().logDefaultNetworkValidity( mDeps.getMetricsLogger() .defaultNetworkMetrics().logDefaultNetworkValidity( SystemClock.elapsedRealtime(), valid); } final int oldScore = nai.getCurrentScore(); Loading Loading @@ -2968,8 +3023,8 @@ public class ConnectivityService extends IConnectivityManager.Stub final boolean wasDefault = isDefaultNetwork(nai); synchronized (mNetworkForNetId) { mNetworkForNetId.remove(nai.network.netId); mNetIdInUse.delete(nai.network.netId); } mNetIdManager.releaseNetId(nai.network.netId); // Just in case. mLegacyTypeTracker.remove(nai, wasDefault); } Loading Loading @@ -3016,7 +3071,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence // whose timestamps tell how long it takes to recover a default network. long now = SystemClock.elapsedRealtime(); metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai); mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai); } notifyIfacesChangedForNetworkStats(); // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied Loading Loading @@ -3070,9 +3125,7 @@ public class ConnectivityService extends IConnectivityManager.Stub destroyNativeNetwork(nai); mDnsManager.removeNetwork(nai.network); } synchronized (mNetworkForNetId) { mNetIdInUse.delete(nai.network.netId); } mNetIdManager.releaseNetId(nai.network.netId); } private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) { Loading Loading @@ -4156,7 +4209,7 @@ public class ConnectivityService extends IConnectivityManager.Stub return null; } return getLinkPropertiesProxyInfo(activeNetwork); } else if (queryUserAccess(Binder.getCallingUid(), network.netId)) { } else if (mDeps.queryUserAccess(Binder.getCallingUid(), network.netId)) { // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which // caller may not have. return getLinkPropertiesProxyInfo(network); Loading @@ -4165,10 +4218,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return null; } @VisibleForTesting protected boolean queryUserAccess(int uid, int netId) { return NetworkUtils.queryUserAccess(uid, netId); } private ProxyInfo getLinkPropertiesProxyInfo(Network network) { final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); Loading Loading @@ -4761,7 +4810,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final long ident = Binder.clearCallingIdentity(); try { // Concatenate the range of types onto the range of NetIDs. int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); mNotifier.setProvNotificationVisible(visible, id, action); } finally { Binder.restoreCallingIdentity(ident); Loading Loading @@ -5372,10 +5421,9 @@ public class ConnectivityService extends IConnectivityManager.Stub @GuardedBy("mNetworkForNetId") private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId. // An entry is first added to mNetIdInUse, prior to mNetworkForNetId, so // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so // there may not be a strict 1:1 correlation between the two. @GuardedBy("mNetworkForNetId") private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray(); private final NetIdManager mNetIdManager; // NetworkAgentInfo keyed off its connecting messenger // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays Loading Loading @@ -5477,9 +5525,9 @@ public class ConnectivityService extends IConnectivityManager.Stub // satisfies mDefaultRequest. final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver, mNMS, factorySerialNumber); new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver, mNMS, factorySerialNumber); // Make sure the network capabilities reflect what the agent info says. nai.setNetworkCapabilities(mixInCapabilities(nai, nc)); final String extraInfo = networkInfo.getExtraInfo(); Loading @@ -5488,7 +5536,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) log("registerNetworkAgent " + nai); final long token = Binder.clearCallingIdentity(); try { getNetworkStack().makeNetworkMonitor( mDeps.getNetworkStack().makeNetworkMonitor( nai.network, name, new NetworkMonitorCallbacks(nai)); } finally { Binder.restoreCallingIdentity(token); Loading @@ -5500,11 +5548,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return nai.network.netId; } @VisibleForTesting protected NetworkStackClient getNetworkStack() { return NetworkStackClient.getInstance(); } private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { nai.onNetworkMonitorCreated(networkMonitor); if (VDBG) log("Got NetworkAgent Messenger"); Loading Loading @@ -6313,7 +6356,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Notify system services that this network is up. makeDefault(newNetwork); // Log 0 -> X and Y -> X default network transitions, where X is the new default. metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent( mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent( now, newNetwork, oldDefaultNetwork); // Have a new default network, release the transition wakelock in scheduleReleaseNetworkTransitionWakelock(); Loading Loading @@ -6990,27 +7033,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return nwm.getWatchlistConfigHash(); } @VisibleForTesting MultinetworkPolicyTracker createMultinetworkPolicyTracker(Context c, Handler h, Runnable r) { return new MultinetworkPolicyTracker(c, h, r); } @VisibleForTesting public WakeupMessage makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj) { return new WakeupMessage(c, h, s, cmd, 0, 0, obj); } @VisibleForTesting public boolean hasService(String name) { return ServiceManager.checkService(name) != null; } @VisibleForTesting protected IpConnectivityMetrics.Logger metricsLogger() { return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class), "no IpConnectivityMetrics service"); } private void logNetworkEvent(NetworkAgentInfo nai, int evtype) { int[] transports = nai.networkCapabilities.getTransportTypes(); mMetricsLog.log(nai.network.netId, transports, new NetworkEvent(evtype)); Loading
services/core/java/com/android/server/IpSecService.java +2 −2 Original line number Diff line number Diff line Loading @@ -750,10 +750,10 @@ public class IpSecService extends IIpSecService.Stub { } } // These values have been reserved in ConnectivityService // These values have been reserved in NetIdManager @VisibleForTesting static final int TUN_INTF_NETID_START = 0xFC00; @VisibleForTesting static final int TUN_INTF_NETID_RANGE = 0x0400; public static final int TUN_INTF_NETID_RANGE = 0x0400; private final SparseBooleanArray mTunnelNetIds = new SparseBooleanArray(); private int mNextTunnelNetIdIndex = 0; Loading
services/core/java/com/android/server/NetIdManager.java 0 → 100644 +76 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import android.annotation.NonNull; import android.util.SparseBooleanArray; import com.android.internal.annotations.GuardedBy; /** * Class used to reserve and release net IDs. * * <p>Instances of this class are thread-safe. */ public class NetIdManager { // Sequence number for Networks; keep in sync with system/netd/NetworkController.cpp public static final int MIN_NET_ID = 100; // some reserved marks // Top IDs reserved by IpSecService public static final int MAX_NET_ID = 65535 - IpSecService.TUN_INTF_NETID_RANGE; @GuardedBy("mNetIdInUse") private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray(); @GuardedBy("mNetIdInUse") private int mLastNetId = MIN_NET_ID - 1; /** * Get the first netId that follows the provided lastId and is available. */ private static int getNextAvailableNetIdLocked( int lastId, @NonNull SparseBooleanArray netIdInUse) { int netId = lastId; for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) { netId = netId < MAX_NET_ID ? netId + 1 : MIN_NET_ID; if (!netIdInUse.get(netId)) { return netId; } } throw new IllegalStateException("No free netIds"); } /** * Reserve a new ID for a network. */ public int reserveNetId() { synchronized (mNetIdInUse) { mLastNetId = getNextAvailableNetIdLocked(mLastNetId, mNetIdInUse); // Make sure NetID unused. http://b/16815182 mNetIdInUse.put(mLastNetId, true); return mLastNetId; } } /** * Clear a previously reserved ID for a network. */ public void releaseNetId(int id) { synchronized (mNetIdInUse) { mNetIdInUse.delete(id); } } }
services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +5 −3 Original line number Diff line number Diff line Loading @@ -580,10 +580,12 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { } if (newExpiry > 0) { mLingerMessage = mConnService.makeWakeupMessage( mLingerMessage = new WakeupMessage( mContext, mHandler, "NETWORK_LINGER_COMPLETE." + network.netId, EVENT_NETWORK_LINGER_COMPLETE, this); "NETWORK_LINGER_COMPLETE." + network.netId /* cmdName */, EVENT_NETWORK_LINGER_COMPLETE /* cmd */, 0 /* arg1 (unused) */, 0 /* arg2 (unused) */, this /* obj (NetworkAgentInfo) */); mLingerMessage.schedule(newExpiry); } Loading
tests/net/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ android_test { "androidx.test.rules", "FrameworksNetCommonTests", "frameworks-base-testutils", "frameworks-net-integration-testutils", "framework-protos", "mockito-target-minus-junit4", "net-tests-utils", Loading