From ce1de180e7652e2b2313b401451ca3d9d027b372 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 20 Jun 2017 16:19:19 -0700 Subject: WifiStateMachine: Increment startup failure metrics Increment the metrics for wifi native start failure reasons. WifiNative.setupForClientMode() and WifiNative.setupForSoftApMode() have been modified to return the reason for failure. WifiStateMachine can now use these reason codes to increment the corresponding metrics. Bug: 38457087 Test: Unit tests Change-Id: I94c4283bac1566c1edd3985d96e6f39b7dd56910 --- .../java/com/android/server/wifi/WifiNative.java | 32 ++++++--- .../com/android/server/wifi/WifiStateMachine.java | 28 +++++++- .../com/android/server/wifi/WifiNativeTest.java | 43 +++++++----- .../android/server/wifi/WifiStateMachineTest.java | 78 +++++++++++++++++++++- 4 files changed, 151 insertions(+), 30 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index aca32bc31..20c9bad26 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -29,6 +29,7 @@ import android.net.wifi.WifiScanner; import android.net.wifi.WifiWakeReasonAndCounts; import android.os.SystemClock; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import com.android.internal.annotations.Immutable; @@ -90,6 +91,9 @@ public class WifiNative { /******************************************************** * Native Initialization/Deinitialization ********************************************************/ + public static final int SETUP_SUCCESS = 0; + public static final int SETUP_FAILURE_HAL = 1; + public static final int SETUP_FAILURE_WIFICOND = 2; /** * Setup wifi native for Client mode operations. @@ -98,15 +102,19 @@ public class WifiNative { * 2. Setup Wificond to operate in client mode and retrieve the handle to use for client * operations. * - * @return An IClientInterface as wificond client interface binder handler. - * Returns null on failure. + * @return Pair of to indicate the status and the associated wificond + * client interface binder handler (will be null on failure). */ - public IClientInterface setupForClientMode() { + public Pair setupForClientMode() { if (!startHalIfNecessary(true)) { Log.e(mTAG, "Failed to start HAL for client mode"); - return null; + return Pair.create(SETUP_FAILURE_HAL, null); + } + IClientInterface iClientInterface = mWificondControl.setupDriverForClientMode(); + if (iClientInterface == null) { + return Pair.create(SETUP_FAILURE_WIFICOND, null); } - return mWificondControl.setupDriverForClientMode(); + return Pair.create(SETUP_SUCCESS, iClientInterface); } /** @@ -115,15 +123,19 @@ public class WifiNative { * 1. Starts the Wifi HAL and configures it in AP mode. * 2. Setup Wificond to operate in AP mode and retrieve the handle to use for ap operations. * - * @return An IApInterface as wificond Ap interface binder handler. - * Returns null on failure. + * @return Pair of to indicate the status and the associated wificond + * AP interface binder handler (will be null on failure). */ - public IApInterface setupForSoftApMode() { + public Pair setupForSoftApMode() { if (!startHalIfNecessary(false)) { Log.e(mTAG, "Failed to start HAL for AP mode"); - return null; + return Pair.create(SETUP_FAILURE_HAL, null); + } + IApInterface iApInterface = mWificondControl.setupDriverForSoftApMode(); + if (iApInterface == null) { + return Pair.create(SETUP_FAILURE_WIFICOND, null); } - return mWificondControl.setupDriverForSoftApMode(); + return Pair.create(SETUP_SUCCESS, iApInterface); } /** diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 0fb61df17..3b6ff817c 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -96,6 +96,7 @@ import android.provider.Settings; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import com.android.internal.R; @@ -3721,6 +3722,17 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss } } + /** + * Helper function to increment the appropriate setup failure metrics. + */ + private void incrementMetricsForSetupFailure(int failureReason) { + if (failureReason == WifiNative.SETUP_FAILURE_HAL) { + mWifiMetrics.incrementNumWifiOnFailureDueToHal(); + } else if (failureReason == WifiNative.SETUP_FAILURE_WIFICOND) { + mWifiMetrics.incrementNumWifiOnFailureDueToWificond(); + } + } + /******************************************************** * HSM states *******************************************************/ @@ -4075,7 +4087,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss logStateAndMessage(message, this); switch (message.what) { case CMD_START_SUPPLICANT: - mClientInterface = mWifiNative.setupForClientMode(); + Pair statusAndInterface = + mWifiNative.setupForClientMode(); + if (statusAndInterface.first == WifiNative.SETUP_SUCCESS) { + mClientInterface = statusAndInterface.second; + } else { + incrementMetricsForSetupFailure(statusAndInterface.first); + } if (mClientInterface == null || !mDeathRecipient.linkToDeath(mClientInterface.asBinder())) { setWifiState(WifiManager.WIFI_STATE_UNKNOWN); @@ -6772,7 +6790,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss SoftApModeConfiguration config = (SoftApModeConfiguration) message.obj; mMode = config.getTargetMode(); - IApInterface apInterface = mWifiNative.setupForSoftApMode(); + IApInterface apInterface = null; + Pair statusAndInterface = mWifiNative.setupForSoftApMode(); + if (statusAndInterface.first == WifiNative.SETUP_SUCCESS) { + apInterface = statusAndInterface.second; + } else { + incrementMetricsForSetupFailure(statusAndInterface.first); + } if (apInterface == null) { setWifiApState(WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL, null, mMode); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java index d58af91fc..32d1daa92 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java @@ -31,6 +31,7 @@ import android.net.wifi.IApInterface; import android.net.wifi.IClientInterface; import android.net.wifi.WifiConfiguration; import android.test.suitebuilder.annotation.SmallTest; +import android.util.Pair; import org.junit.Before; import org.junit.Test; @@ -487,8 +488,9 @@ public class WifiNativeTest { IClientInterface clientInterface = mock(IClientInterface.class); when(mWificondControl.setupDriverForClientMode()).thenReturn(clientInterface); - IClientInterface returnedClientInterface = mWifiNative.setupForClientMode(); - assertEquals(clientInterface, returnedClientInterface); + Pair statusAndClientInterface = mWifiNative.setupForClientMode(); + assertTrue(WifiNative.SETUP_SUCCESS == statusAndClientInterface.first); + assertEquals(clientInterface, statusAndClientInterface.second); verify(mWifiVendorHal).startVendorHal(eq(true)); verify(mWificondControl).setupDriverForClientMode(); } @@ -503,8 +505,9 @@ public class WifiNativeTest { IClientInterface clientInterface = mock(IClientInterface.class); when(mWificondControl.setupDriverForClientMode()).thenReturn(clientInterface); - IClientInterface returnedClientInterface = mWifiNative.setupForClientMode(); - assertEquals(clientInterface, returnedClientInterface); + Pair statusAndClientInterface = mWifiNative.setupForClientMode(); + assertTrue(WifiNative.SETUP_SUCCESS == statusAndClientInterface.first); + assertEquals(clientInterface, statusAndClientInterface.second); verify(mWifiVendorHal, never()).startVendorHal(anyBoolean()); verify(mWificondControl).setupDriverForClientMode(); } @@ -517,8 +520,9 @@ public class WifiNativeTest { public void testSetupDriverForClientModeWificondError() { when(mWificondControl.setupDriverForClientMode()).thenReturn(null); - IClientInterface returnedClientInterface = mWifiNative.setupForClientMode(); - assertEquals(null, returnedClientInterface); + Pair statusAndClientInterface = mWifiNative.setupForClientMode(); + assertTrue(WifiNative.SETUP_FAILURE_WIFICOND == statusAndClientInterface.first); + assertEquals(null, statusAndClientInterface.second); verify(mWifiVendorHal).startVendorHal(eq(true)); verify(mWificondControl).setupDriverForClientMode(); } @@ -530,8 +534,9 @@ public class WifiNativeTest { public void testSetupDriverForClientModeHalError() { when(mWifiVendorHal.startVendorHal(anyBoolean())).thenReturn(false); - IClientInterface returnedClientInterface = mWifiNative.setupForClientMode(); - assertEquals(null, returnedClientInterface); + Pair statusAndClientInterface = mWifiNative.setupForClientMode(); + assertTrue(WifiNative.SETUP_FAILURE_HAL == statusAndClientInterface.first); + assertEquals(null, statusAndClientInterface.second); verify(mWifiVendorHal).startVendorHal(eq(true)); verify(mWificondControl, never()).setupDriverForClientMode(); } @@ -544,8 +549,9 @@ public class WifiNativeTest { IApInterface apInterface = mock(IApInterface.class); when(mWificondControl.setupDriverForSoftApMode()).thenReturn(apInterface); - IApInterface returnedApInterface = mWifiNative.setupForSoftApMode(); - assertEquals(apInterface, returnedApInterface); + Pair statusAndApInterface = mWifiNative.setupForSoftApMode(); + assertTrue(WifiNative.SETUP_SUCCESS == statusAndApInterface.first); + assertEquals(apInterface, statusAndApInterface.second); verify(mWifiVendorHal).startVendorHal(eq(false)); verify(mWificondControl).setupDriverForSoftApMode(); } @@ -560,8 +566,9 @@ public class WifiNativeTest { IApInterface apInterface = mock(IApInterface.class); when(mWificondControl.setupDriverForSoftApMode()).thenReturn(apInterface); - IApInterface returnedApInterface = mWifiNative.setupForSoftApMode(); - assertEquals(apInterface, returnedApInterface); + Pair statusAndApInterface = mWifiNative.setupForSoftApMode(); + assertTrue(WifiNative.SETUP_SUCCESS == statusAndApInterface.first); + assertEquals(apInterface, statusAndApInterface.second); verify(mWifiVendorHal, never()).startVendorHal(anyBoolean()); verify(mWificondControl).setupDriverForSoftApMode(); } @@ -573,9 +580,11 @@ public class WifiNativeTest { @Test public void testSetupDriverForSoftApModeWificondError() { when(mWificondControl.setupDriverForSoftApMode()).thenReturn(null); - IApInterface returnedApInterface = mWifiNative.setupForSoftApMode(); - assertEquals(null, returnedApInterface); + Pair statusAndApInterface = mWifiNative.setupForSoftApMode(); + assertTrue(WifiNative.SETUP_FAILURE_WIFICOND == statusAndApInterface.first); + assertEquals(null, statusAndApInterface.second); + verify(mWifiVendorHal).startVendorHal(eq(false)); verify(mWificondControl).setupDriverForSoftApMode(); } @@ -587,8 +596,10 @@ public class WifiNativeTest { public void testSetupDriverForSoftApModeHalError() { when(mWifiVendorHal.startVendorHal(anyBoolean())).thenReturn(false); - IApInterface returnedApInterface = mWifiNative.setupForSoftApMode(); - assertEquals(null, returnedApInterface); + Pair statusAndApInterface = mWifiNative.setupForSoftApMode(); + assertTrue(WifiNative.SETUP_FAILURE_HAL == statusAndApInterface.first); + assertEquals(null, statusAndApInterface.second); + verify(mWifiVendorHal).startVendorHal(eq(false)); verify(mWificondControl, never()).setupDriverForSoftApMode(); } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index f2ec4d709..4568b743e 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -84,6 +84,7 @@ import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import com.android.internal.R; @@ -379,8 +380,10 @@ public class WifiStateMachineTest { when(mWifiInjector.getWifiNative()).thenReturn(mWifiNative); when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery); - when(mWifiNative.setupForClientMode()).thenReturn(mClientInterface); - when(mWifiNative.setupForSoftApMode()).thenReturn(mApInterface); + when(mWifiNative.setupForClientMode()) + .thenReturn(Pair.create(WifiNative.SETUP_SUCCESS, mClientInterface)); + when(mWifiNative.setupForSoftApMode()) + .thenReturn(Pair.create(WifiNative.SETUP_SUCCESS, mApInterface)); when(mApInterface.getInterfaceName()).thenReturn(WIFI_IFACE_NAME); when(mWifiNative.getInterfaceName()).thenReturn(WIFI_IFACE_NAME); when(mWifiNative.enableSupplicant()).thenReturn(true); @@ -501,6 +504,7 @@ public class WifiStateMachineTest { assertEquals("SoftApState", getCurrentState().getName()); + verify(mWifiNative).setupForSoftApMode(); verify(mSoftApManager).start(); // reset expectations for mContext due to previously sent AP broadcast @@ -1794,4 +1798,74 @@ public class WifiStateMachineTest { mLooper.stopAutoDispatch(); assertFalse(succeeded); } + + /** + * Test that failure to start HAL in AP mode increments the corresponding metrics. + */ + @Test + public void testSetupForSoftApModeHalFailureIncrementsMetrics() throws Exception { + when(mWifiNative.setupForSoftApMode()) + .thenReturn(Pair.create(WifiNative.SETUP_FAILURE_HAL, null)); + + SoftApModeConfiguration config = new SoftApModeConfiguration( + WifiManager.IFACE_IP_MODE_TETHERED, new WifiConfiguration()); + mWsm.setHostApRunning(config, true); + mLooper.dispatchAll(); + + verify(mWifiNative).setupForSoftApMode(); + verify(mWifiMetrics).incrementNumWifiOnFailureDueToHal(); + } + + /** + * Test that failure to start HAL in AP mode increments the corresponding metrics. + */ + @Test + public void testSetupForSoftApModeWificondFailureIncrementsMetrics() throws Exception { + when(mWifiNative.setupForSoftApMode()) + .thenReturn(Pair.create(WifiNative.SETUP_FAILURE_WIFICOND, null)); + + SoftApModeConfiguration config = new SoftApModeConfiguration( + WifiManager.IFACE_IP_MODE_TETHERED, new WifiConfiguration()); + mWsm.setHostApRunning(config, true); + mLooper.dispatchAll(); + + verify(mWifiNative).setupForSoftApMode(); + verify(mWifiMetrics).incrementNumWifiOnFailureDueToWificond(); + } + + /** + * Test that failure to start HAL in client mode increments the corresponding metrics. + */ + @Test + public void testSetupForClientModeHalFailureIncrementsMetrics() throws Exception { + when(mWifiNative.setupForClientMode()) + .thenReturn(Pair.create(WifiNative.SETUP_FAILURE_HAL, null)); + + mWsm.setSupplicantRunning(true); + mLooper.dispatchAll(); + + mWsm.sendMessage(WifiMonitor.SUP_CONNECTION_EVENT); + mLooper.dispatchAll(); + + verify(mWifiNative).setupForClientMode(); + verify(mWifiMetrics).incrementNumWifiOnFailureDueToHal(); + } + + /** + * Test that failure to start HAL in client mode increments the corresponding metrics. + */ + @Test + public void testSetupForClientModeWificondFailureIncrementsMetrics() throws Exception { + when(mWifiNative.setupForClientMode()) + .thenReturn(Pair.create(WifiNative.SETUP_FAILURE_WIFICOND, null)); + + mWsm.setSupplicantRunning(true); + mLooper.dispatchAll(); + + mWsm.sendMessage(WifiMonitor.SUP_CONNECTION_EVENT); + mLooper.dispatchAll(); + + verify(mWifiNative).setupForClientMode(); + verify(mWifiMetrics).incrementNumWifiOnFailureDueToWificond(); + } } -- cgit v1.2.3