Split untrusted NetworkFactory from regular one.

This ensures that mConnectionRequests is managed exactly the same way
as it is in standard builds, while still making sure that we see all
requests for untrusted networks.

Bug: 18815795
Change-Id: I9aaba6095b934fee27a27b20fa3adb2a10648e80
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 6944461..c2eff96 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -138,6 +138,7 @@
 public class WifiStateMachine extends StateMachine {
 
     private static final String NETWORKTYPE = "WIFI";
+    private static final String NETWORKTYPE_UNTRUSTED = "WIFI_UT";
     private static boolean DBG = false;
     private static boolean VDBG = false;
     private static boolean VVDBG = false;
@@ -407,6 +408,7 @@
 
     private int mConnectionRequests = 0;
     private WifiNetworkFactory mNetworkFactory;
+    private UntrustedWifiNetworkFactory mUntrustedNetworkFactory;
     private WifiNetworkAgent mNetworkAgent;
 
     // Keep track of various statistics, for retrieval by System Apps, i.e. under @SystemApi
@@ -2432,6 +2434,7 @@
         pw.println("mLastSetCountryCode " + mLastSetCountryCode);
         pw.println("mPersistedCountryCode " + mPersistedCountryCode);
         mNetworkFactory.dump(fd, pw, args);
+        mUntrustedNetworkFactory.dump(fd, pw, args);
         pw.println();
         mWifiConfigStore.dump(fd, pw, args);
     }
@@ -4595,9 +4598,6 @@
     }
 
     private class WifiNetworkFactory extends NetworkFactory {
-        /** Number of outstanding NetworkRequests for untrusted networks. */
-        private int mUntrustedReqCount = 0;
-
         public WifiNetworkFactory(Looper l, Context c, String TAG, NetworkCapabilities f) {
             super(l, c, TAG, f);
         }
@@ -4605,6 +4605,28 @@
         @Override
         protected void needNetworkFor(NetworkRequest networkRequest, int score) {
             ++mConnectionRequests;
+        }
+
+        @Override
+        protected void releaseNetworkFor(NetworkRequest networkRequest) {
+            --mConnectionRequests;
+        }
+
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            pw.println("mConnectionRequests " + mConnectionRequests);
+        }
+
+    }
+
+    private class UntrustedWifiNetworkFactory extends NetworkFactory {
+        private int mUntrustedReqCount;
+
+        public UntrustedWifiNetworkFactory(Looper l, Context c, String tag, NetworkCapabilities f) {
+            super(l, c, tag, f);
+        }
+
+        @Override
+        protected void needNetworkFor(NetworkRequest networkRequest, int score) {
             if (!networkRequest.networkCapabilities.hasCapability(
                     NetworkCapabilities.NET_CAPABILITY_TRUSTED)) {
                 if (++mUntrustedReqCount == 1) {
@@ -4615,7 +4637,6 @@
 
         @Override
         protected void releaseNetworkFor(NetworkRequest networkRequest) {
-            --mConnectionRequests;
             if (!networkRequest.networkCapabilities.hasCapability(
                     NetworkCapabilities.NET_CAPABILITY_TRUSTED)) {
                 if (--mUntrustedReqCount == 0) {
@@ -4625,10 +4646,8 @@
         }
 
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            pw.println("mConnectionRequests " + mConnectionRequests);
             pw.println("mUntrustedReqCount " + mUntrustedReqCount);
         }
-
     }
 
     void maybeRegisterNetworkFactory() {
@@ -4639,6 +4658,13 @@
                         NETWORKTYPE, mNetworkCapabilitiesFilter);
                 mNetworkFactory.setScoreFilter(60);
                 mNetworkFactory.register();
+
+                // We can't filter untrusted network in the capabilities filter because a trusted
+                // network would still satisfy a request that accepts untrusted ones.
+                mUntrustedNetworkFactory = new UntrustedWifiNetworkFactory(getHandler().getLooper(),
+                        mContext, NETWORKTYPE_UNTRUSTED, mNetworkCapabilitiesFilter);
+                mUntrustedNetworkFactory.setScoreFilter(Integer.MAX_VALUE);
+                mUntrustedNetworkFactory.register();
             }
         }
     }