Add EAP methods in WifiMetrics

To help find the root cause of high authentication failure rate in enterprise network, add EAP method and authentication phase2 method in connection event metrics.

Bug: 150237135
Test: manual
Test: atest com.android.server.wifi
Change-Id: I0c4ab436b1e43cc52d4bd4dab6c01db53fec91a6
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 7578d37..6db4e99 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -26,6 +26,7 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.SupplicantState;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.DeviceMobilityState;
@@ -480,6 +481,8 @@
                 sb.append(", mHidden=" + mRouterFingerPrintProto.hidden);
                 sb.append(", mRouterTechnology=" + mRouterFingerPrintProto.routerTechnology);
                 sb.append(", mSupportsIpv6=" + mRouterFingerPrintProto.supportsIpv6);
+                sb.append(", mEapMethod=" + mRouterFingerPrintProto.eapMethod);
+                sb.append(", mAuthPhase2Method=" + mRouterFingerPrintProto.authPhase2Method);
             }
             return sb.toString();
         }
@@ -516,9 +519,61 @@
                     if (candidate != null) {
                         updateMetricsFromScanResult(candidate);
                     }
+                    if (mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
+                            .authentication == WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE
+                            && config.enterpriseConfig != null) {
+                        int eapMethod = config.enterpriseConfig.getEapMethod();
+                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
+                                .eapMethod = getEapMethodProto(eapMethod);
+                        int phase2Method = config.enterpriseConfig.getPhase2Method();
+                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
+                                .authPhase2Method = getAuthPhase2MethodProto(phase2Method);
+                    }
                 }
             }
         }
+        private int getEapMethodProto(int eapMethod) {
+            switch (eapMethod) {
+                case WifiEnterpriseConfig.Eap.TLS:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_TLS;
+                case WifiEnterpriseConfig.Eap.UNAUTH_TLS:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_UNAUTH_TLS;
+                case WifiEnterpriseConfig.Eap.PEAP:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_PEAP;
+                case WifiEnterpriseConfig.Eap.PWD:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_PWD;
+                case WifiEnterpriseConfig.Eap.TTLS:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_TTLS;
+                case WifiEnterpriseConfig.Eap.SIM:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_SIM;
+                case WifiEnterpriseConfig.Eap.AKA:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_AKA;
+                case WifiEnterpriseConfig.Eap.AKA_PRIME:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_AKA_PRIME;
+                default:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_UNKNOWN;
+            }
+        }
+        private int getAuthPhase2MethodProto(int phase2Method) {
+            switch (phase2Method) {
+                case WifiEnterpriseConfig.Phase2.PAP:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_PAP;
+                case WifiEnterpriseConfig.Phase2.MSCHAP:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_MSCHAP;
+                case WifiEnterpriseConfig.Phase2.MSCHAPV2:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_MSCHAPV2;
+                case WifiEnterpriseConfig.Phase2.GTC:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_GTC;
+                case WifiEnterpriseConfig.Phase2.SIM:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_SIM;
+                case WifiEnterpriseConfig.Phase2.AKA:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_AKA;
+                case WifiEnterpriseConfig.Phase2.AKA_PRIME:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_AKA_PRIME;
+                default:
+                    return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_NONE;
+            }
+        }
     }
 
     /**
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 73ac30f..1176957 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -58,6 +58,7 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.SupplicantState;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiSsid;
@@ -1371,10 +1372,17 @@
         when(networkDetail.getDtimInterval()).thenReturn(NETWORK_DETAIL_DTIM);
         ScanResult scanResult = mock(ScanResult.class);
         scanResult.level = SCAN_RESULT_LEVEL;
+        scanResult.capabilities = "EAP";
         WifiConfiguration config = mock(WifiConfiguration.class);
         config.SSID = "\"" + SSID + "\"";
         config.dtimInterval = CONFIG_DTIM;
         config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
+        config.allowedKeyManagement = new BitSet();
+        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
+        config.enterpriseConfig = new WifiEnterpriseConfig();
+        config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
+        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
         WifiConfiguration.NetworkSelectionStatus networkSelectionStat =
                 mock(WifiConfiguration.NetworkSelectionStatus.class);
         when(networkSelectionStat.getCandidate()).thenReturn(scanResult);
@@ -1395,7 +1403,9 @@
                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
 
+        //Change configuration to open without randomization
         config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
+        scanResult.capabilities = "";
         //Create a connection event using the config and a scan detail
         mWifiMetrics.startConnectionEvent(config, "Green",
                 WifiMetricsProto.ConnectionEvent.ROAM_NONE);
@@ -1411,8 +1421,20 @@
         //Check that the correct values are being flowed through
         assertEquals(2, mDecodedProto.connectionEvent.length);
         assertEquals(CONFIG_DTIM, mDecodedProto.connectionEvent[0].routerFingerprint.dtim);
+        assertEquals(WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE,
+                mDecodedProto.connectionEvent[0].routerFingerprint.authentication);
+        assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_EAP_TTLS,
+                mDecodedProto.connectionEvent[0].routerFingerprint.eapMethod);
+        assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_MSCHAPV2,
+                mDecodedProto.connectionEvent[0].routerFingerprint.authPhase2Method);
         assertEquals(SCAN_RESULT_LEVEL, mDecodedProto.connectionEvent[0].signalStrength);
         assertEquals(NETWORK_DETAIL_DTIM, mDecodedProto.connectionEvent[1].routerFingerprint.dtim);
+        assertEquals(WifiMetricsProto.RouterFingerPrint.AUTH_OPEN,
+                mDecodedProto.connectionEvent[1].routerFingerprint.authentication);
+        assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_EAP_UNKNOWN,
+                mDecodedProto.connectionEvent[1].routerFingerprint.eapMethod);
+        assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_NONE,
+                mDecodedProto.connectionEvent[1].routerFingerprint.authPhase2Method);
         assertEquals(SCAN_RESULT_LEVEL, mDecodedProto.connectionEvent[1].signalStrength);
         assertEquals(NETWORK_DETAIL_WIFIMODE,
                 mDecodedProto.connectionEvent[1].routerFingerprint.routerTechnology);