Loading services/core/java/com/android/server/ConnectivityService.java +29 −0 Original line number Diff line number Diff line Loading @@ -2330,6 +2330,18 @@ public class ConnectivityService extends IConnectivityManager.Stub if (VDBG || (DBG && nri.isRequest())) log("releasing NetworkRequest " + request); nri.unlinkDeathRecipient(); mNetworkRequests.remove(request); synchronized (mUidToNetworkRequestCount) { int requests = mUidToNetworkRequestCount.get(nri.mUid, 0); if (requests < 1) { Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " + nri.mUid); } else if (requests == 1) { mUidToNetworkRequestCount.removeAt( mUidToNetworkRequestCount.indexOfKey(nri.mUid)); } else { mUidToNetworkRequestCount.put(nri.mUid, requests - 1); } } mNetworkRequestInfoLogs.log("RELEASE " + nri); if (nri.isRequest()) { // Find all networks that are satisfying this request and remove the request Loading Loading @@ -3677,6 +3689,11 @@ public class ConnectivityService extends IConnectivityManager.Stub private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<NetworkRequest, NetworkRequestInfo>(); private static final int MAX_NETWORK_REQUESTS_PER_UID = 100; // Map from UID to number of NetworkRequests that UID has filed. @GuardedBy("mUidToNetworkRequestCount") private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray(); private static class NetworkFactoryInfo { public final String name; public final Messenger messenger; Loading Loading @@ -3737,6 +3754,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mPid = getCallingPid(); mUid = getCallingUid(); mType = type; enforceRequestCountLimit(); } NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, NetworkRequestType type) { Loading @@ -3748,6 +3766,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mUid = getCallingUid(); mType = type; mPendingIntent = null; enforceRequestCountLimit(); try { mBinder.linkToDeath(this, 0); Loading @@ -3756,6 +3775,16 @@ public class ConnectivityService extends IConnectivityManager.Stub } } private void enforceRequestCountLimit() { synchronized (mUidToNetworkRequestCount) { int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1; if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) { throw new IllegalArgumentException("Too many NetworkRequests filed"); } mUidToNetworkRequestCount.put(mUid, networkRequests); } } private String typeString() { switch (mType) { case LISTEN: return "Listen"; Loading services/tests/servicestests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" /> <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" /> <application> <uses-library android:name="android.test.runner" /> Loading services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +93 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult; import com.android.server.net.NetworkPinner; import java.net.InetAddress; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; Loading Loading @@ -1788,4 +1789,96 @@ public class ConnectivityServiceTest extends AndroidTestCase { waitFor(cv); assertPinnedToWifiWithCellDefault(); } @SmallTest public void testNetworkRequestMaximum() { final int MAX_REQUESTS = 100; // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. NetworkRequest networkRequest = new NetworkRequest.Builder().build(); ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>(); try { for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.requestNetwork(networkRequest, networkCallback); networkCallbacks.add(networkCallback); } fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception"); } catch (IllegalArgumentException expected) {} for (NetworkCallback networkCallback : networkCallbacks) { mCm.unregisterNetworkCallback(networkCallback); } networkCallbacks.clear(); try { for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.registerNetworkCallback(networkRequest, networkCallback); networkCallbacks.add(networkCallback); } fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception"); } catch (IllegalArgumentException expected) {} for (NetworkCallback networkCallback : networkCallbacks) { mCm.unregisterNetworkCallback(networkCallback); } networkCallbacks.clear(); ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>(); try { for (int i = 0; i < MAX_REQUESTS + 1; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0); mCm.requestNetwork(networkRequest, pendingIntent); pendingIntents.add(pendingIntent); } fail("Registering " + MAX_REQUESTS + " PendingIntent NetworkRequests did not throw exception"); } catch (IllegalArgumentException expected) {} for (PendingIntent pendingIntent : pendingIntents) { mCm.unregisterNetworkCallback(pendingIntent); } pendingIntents.clear(); try { for (int i = 0; i < MAX_REQUESTS + 1; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0); mCm.registerNetworkCallback(networkRequest, pendingIntent); pendingIntents.add(pendingIntent); } fail("Registering " + MAX_REQUESTS + " PendingIntent NetworkCallbacks did not throw exception"); } catch (IllegalArgumentException expected) {} for (PendingIntent pendingIntent : pendingIntents) { mCm.unregisterNetworkCallback(pendingIntent); } pendingIntents.clear(); mService.waitForIdle(5000); // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.requestNetwork(networkRequest, networkCallback); mCm.unregisterNetworkCallback(networkCallback); } mService.waitForIdle(); for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.registerNetworkCallback(networkRequest, networkCallback); mCm.unregisterNetworkCallback(networkCallback); } mService.waitForIdle(); for (int i = 0; i < MAX_REQUESTS; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0); mCm.requestNetwork(networkRequest, pendingIntent); mCm.unregisterNetworkCallback(pendingIntent); } mService.waitForIdle(); for (int i = 0; i < MAX_REQUESTS; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0); mCm.registerNetworkCallback(networkRequest, pendingIntent); mCm.unregisterNetworkCallback(pendingIntent); } } } Loading
services/core/java/com/android/server/ConnectivityService.java +29 −0 Original line number Diff line number Diff line Loading @@ -2330,6 +2330,18 @@ public class ConnectivityService extends IConnectivityManager.Stub if (VDBG || (DBG && nri.isRequest())) log("releasing NetworkRequest " + request); nri.unlinkDeathRecipient(); mNetworkRequests.remove(request); synchronized (mUidToNetworkRequestCount) { int requests = mUidToNetworkRequestCount.get(nri.mUid, 0); if (requests < 1) { Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " + nri.mUid); } else if (requests == 1) { mUidToNetworkRequestCount.removeAt( mUidToNetworkRequestCount.indexOfKey(nri.mUid)); } else { mUidToNetworkRequestCount.put(nri.mUid, requests - 1); } } mNetworkRequestInfoLogs.log("RELEASE " + nri); if (nri.isRequest()) { // Find all networks that are satisfying this request and remove the request Loading Loading @@ -3677,6 +3689,11 @@ public class ConnectivityService extends IConnectivityManager.Stub private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<NetworkRequest, NetworkRequestInfo>(); private static final int MAX_NETWORK_REQUESTS_PER_UID = 100; // Map from UID to number of NetworkRequests that UID has filed. @GuardedBy("mUidToNetworkRequestCount") private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray(); private static class NetworkFactoryInfo { public final String name; public final Messenger messenger; Loading Loading @@ -3737,6 +3754,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mPid = getCallingPid(); mUid = getCallingUid(); mType = type; enforceRequestCountLimit(); } NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, NetworkRequestType type) { Loading @@ -3748,6 +3766,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mUid = getCallingUid(); mType = type; mPendingIntent = null; enforceRequestCountLimit(); try { mBinder.linkToDeath(this, 0); Loading @@ -3756,6 +3775,16 @@ public class ConnectivityService extends IConnectivityManager.Stub } } private void enforceRequestCountLimit() { synchronized (mUidToNetworkRequestCount) { int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1; if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) { throw new IllegalArgumentException("Too many NetworkRequests filed"); } mUidToNetworkRequestCount.put(mUid, networkRequests); } } private String typeString() { switch (mType) { case LISTEN: return "Listen"; Loading
services/tests/servicestests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" /> <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" /> <application> <uses-library android:name="android.test.runner" /> Loading
services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +93 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult; import com.android.server.net.NetworkPinner; import java.net.InetAddress; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; Loading Loading @@ -1788,4 +1789,96 @@ public class ConnectivityServiceTest extends AndroidTestCase { waitFor(cv); assertPinnedToWifiWithCellDefault(); } @SmallTest public void testNetworkRequestMaximum() { final int MAX_REQUESTS = 100; // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. NetworkRequest networkRequest = new NetworkRequest.Builder().build(); ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>(); try { for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.requestNetwork(networkRequest, networkCallback); networkCallbacks.add(networkCallback); } fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception"); } catch (IllegalArgumentException expected) {} for (NetworkCallback networkCallback : networkCallbacks) { mCm.unregisterNetworkCallback(networkCallback); } networkCallbacks.clear(); try { for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.registerNetworkCallback(networkRequest, networkCallback); networkCallbacks.add(networkCallback); } fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception"); } catch (IllegalArgumentException expected) {} for (NetworkCallback networkCallback : networkCallbacks) { mCm.unregisterNetworkCallback(networkCallback); } networkCallbacks.clear(); ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>(); try { for (int i = 0; i < MAX_REQUESTS + 1; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0); mCm.requestNetwork(networkRequest, pendingIntent); pendingIntents.add(pendingIntent); } fail("Registering " + MAX_REQUESTS + " PendingIntent NetworkRequests did not throw exception"); } catch (IllegalArgumentException expected) {} for (PendingIntent pendingIntent : pendingIntents) { mCm.unregisterNetworkCallback(pendingIntent); } pendingIntents.clear(); try { for (int i = 0; i < MAX_REQUESTS + 1; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0); mCm.registerNetworkCallback(networkRequest, pendingIntent); pendingIntents.add(pendingIntent); } fail("Registering " + MAX_REQUESTS + " PendingIntent NetworkCallbacks did not throw exception"); } catch (IllegalArgumentException expected) {} for (PendingIntent pendingIntent : pendingIntents) { mCm.unregisterNetworkCallback(pendingIntent); } pendingIntents.clear(); mService.waitForIdle(5000); // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.requestNetwork(networkRequest, networkCallback); mCm.unregisterNetworkCallback(networkCallback); } mService.waitForIdle(); for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.registerNetworkCallback(networkRequest, networkCallback); mCm.unregisterNetworkCallback(networkCallback); } mService.waitForIdle(); for (int i = 0; i < MAX_REQUESTS; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0); mCm.requestNetwork(networkRequest, pendingIntent); mCm.unregisterNetworkCallback(pendingIntent); } mService.waitForIdle(); for (int i = 0; i < MAX_REQUESTS; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0); mCm.registerNetworkCallback(networkRequest, pendingIntent); mCm.unregisterNetworkCallback(pendingIntent); } } }