diff options
author | Roshan Pius <rpius@google.com> | 2018-12-04 08:22:30 -0800 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2018-12-06 14:20:59 -0800 |
commit | 90c812d29c263b265bc8c2f1dacb6636ae61e6de (patch) | |
tree | 3ae1a6afd74a0075d28f5bc943f5ce25473616a0 | |
parent | 56ada4f17193a6e6a90dea7ffe0c9a37920cd952 (diff) | |
download | android_frameworks_opt_net_wifi-90c812d29c263b265bc8c2f1dacb6636ae61e6de.tar.gz android_frameworks_opt_net_wifi-90c812d29c263b265bc8c2f1dacb6636ae61e6de.tar.bz2 android_frameworks_opt_net_wifi-90c812d29c263b265bc8c2f1dacb6636ae61e6de.zip |
WifiNetworkFactory: Handle wifi toggle
Abort any ongoing requests and reject any new requests when wifi is
toggled off.
Bug: 120477750
Test: ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: Ie7bc6908ecbba0ea25f2eea1a53793384fd178bd
4 files changed, 147 insertions, 3 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index fa64a7034..312574d9a 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -3741,6 +3741,7 @@ public class ClientModeImpl extends StateMachine { // Inform WifiConnectivityManager that Wifi is enabled mWifiConnectivityManager.setWifiEnabled(true); + mNetworkFactory.setWifiState(true); // Inform metrics that Wifi is Enabled (but not yet connected) mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); mWifiMetrics.logStaEvent(StaEvent.TYPE_WIFI_ENABLED); @@ -3757,6 +3758,7 @@ public class ClientModeImpl extends StateMachine { // Inform WifiConnectivityManager that Wifi is disabled mWifiConnectivityManager.setWifiEnabled(false); + mNetworkFactory.setWifiState(false); // Inform metrics that Wifi is being disabled (Toggled, airplane enabled, etc) mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISABLED); mWifiMetrics.logStaEvent(StaEvent.TYPE_WIFI_DISABLED); diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java index e3a8d5c32..3e757ee8f 100644 --- a/service/java/com/android/server/wifi/WifiNetworkFactory.java +++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java @@ -105,6 +105,7 @@ public class WifiNetworkFactory extends NetworkFactory { private boolean mConnectionTimeoutSet = false; private boolean mIsConnectedToUserSelectedNetwork = false; private boolean mIsPeriodicScanPaused = false; + private boolean mWifiEnabled = false; // Scan listener for scan requests. private class NetworkFactoryScanListener implements WifiScanner.ScanListener { @@ -315,6 +316,10 @@ public class WifiNetworkFactory extends NetworkFactory { Log.e(TAG, "Invalid network specifier mentioned. Rejecting"); return false; } + if (!mWifiEnabled) { + Log.e(TAG, "Wifi off. Rejecting"); + return false; + } WifiNetworkSpecifier wns = (WifiNetworkSpecifier) ns; if (!WifiConfigurationUtil.validateNetworkSpecifier(wns)) { @@ -375,6 +380,10 @@ public class WifiNetworkFactory extends NetworkFactory { Log.e(TAG, "Invalid network specifier mentioned. Rejecting"); return; } + if (!mWifiEnabled) { + Log.e(TAG, "Wifi off. Rejecting"); + return; + } retrieveWifiScanner(); // Reset state from any previous request. resetStateForActiveRequestStart(); @@ -408,7 +417,11 @@ public class WifiNetworkFactory extends NetworkFactory { } else { // Invalid network specifier. if (!(ns instanceof WifiNetworkSpecifier)) { - Log.e(TAG, "Invalid network specifier mentioned. Ingoring"); + Log.e(TAG, "Invalid network specifier mentioned. Ignoring"); + return; + } + if (!mWifiEnabled) { + Log.e(TAG, "Wifi off. Ignoring"); return; } if (mActiveSpecificNetworkRequest == null) { @@ -592,6 +605,22 @@ public class WifiNetworkFactory extends NetworkFactory { } } + /** + * Invoked by {@link ClientModeImpl} to indicate wifi state toggle. + */ + public void setWifiState(boolean enabled) { + if (mVerboseLoggingEnabled) Log.v(TAG, "setWifiState " + enabled); + if (enabled) { + reevaluateAllRequests(); // Re-evaluate any pending requests. + } else { + if (mActiveSpecificNetworkRequest != null) { + Log.w(TAG, "Wifi off, cancelling " + mActiveSpecificNetworkRequest); + resetStateForActiveRequestEnd(); + } + } + mWifiEnabled = enabled; + } + private void resetState() { if (mIsConnectedToUserSelectedNetwork) { Log.i(TAG, "Disconnecting from network on reset"); @@ -757,7 +786,7 @@ public class WifiNetworkFactory extends NetworkFactory { } } if (mVerboseLoggingEnabled) { - Log.e(TAG, "List of scan results matching the active request " + Log.v(TAG, "List of scan results matching the active request " + matchedScanResults); } return matchedScanResults; diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index d74afa887..6641f6cc3 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -1776,7 +1776,7 @@ public class ClientModeImplTest { */ @Test public void testWifiInfoCleanedUpEnteringExitingConnectModeState() throws Exception { - InOrder inOrder = inOrder(mWifiConnectivityManager); + InOrder inOrder = inOrder(mWifiConnectivityManager, mWifiNetworkFactory); InOrder inOrderSarMgr = inOrder(mSarManager); InOrder inOrderMetrics = inOrder(mWifiMetrics); Log.i(TAG, mCmi.getCurrentState().getName()); @@ -1789,6 +1789,7 @@ public class ClientModeImplTest { assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true)); + inOrder.verify(mWifiNetworkFactory).setWifiState(eq(true)); inOrderSarMgr.verify(mSarManager).setClientWifiState(WifiManager.WIFI_STATE_ENABLED); inOrderMetrics.verify(mWifiMetrics) .setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); @@ -1812,6 +1813,7 @@ public class ClientModeImplTest { assertEquals("DefaultState", getCurrentState().getName()); assertEquals(WifiManager.WIFI_STATE_DISABLED, mCmi.syncGetWifiState()); inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(false)); + inOrder.verify(mWifiNetworkFactory).setWifiState(eq(false)); inOrderSarMgr.verify(mSarManager).setClientWifiState(WifiManager.WIFI_STATE_DISABLED); inOrderMetrics.verify(mWifiMetrics).setWifiState(WifiMetricsProto.WifiLog.WIFI_DISABLED); inOrderMetrics.verify(mWifiMetrics).logStaEvent(StaEvent.TYPE_WIFI_DISABLED); @@ -1835,6 +1837,7 @@ public class ClientModeImplTest { assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest()); assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true)); + inOrder.verify(mWifiNetworkFactory).setWifiState(eq(true)); inOrderSarMgr.verify(mSarManager).setClientWifiState(WifiManager.WIFI_STATE_ENABLED); inOrderMetrics.verify(mWifiMetrics) .setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java index 6a3b83ddc..43a7b7122 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java @@ -19,6 +19,7 @@ package com.android.server.wifi; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; +import static android.net.NetworkFactory.CMD_REQUEST_NETWORK; import static com.android.server.wifi.WifiNetworkFactory.PERIODIC_SCAN_INTERVAL_MS; import static com.android.server.wifi.util.NativeUtil.addEnclosingQuotes; @@ -34,6 +35,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.net.MacAddress; import android.net.NetworkCapabilities; +import android.net.NetworkFactory; import android.net.NetworkRequest; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.INetworkRequestUserSelectionCallback; @@ -151,6 +153,9 @@ public class WifiNetworkFactoryTest { mNetworkRequest = new NetworkRequest.Builder() .setCapabilities(mNetworkCapabilities) .build(); + + // Setup with wifi on. + mWifiNetworkFactory.setWifiState(true); } /** @@ -1327,6 +1332,111 @@ public class WifiNetworkFactoryTest { mInOrder.verifyNoMoreInteractions(); } + /** + * Verify we don't accept specific network request when wifi is off. + */ + @Test + public void testHandleAcceptNetworkRequestWithSpecifierWhenWifiOff() throws Exception { + when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1)) + .thenReturn(IMPORTANCE_FOREGROUND); + + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + + // set wifi off. + mWifiNetworkFactory.setWifiState(false); + assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + + // set wifi on. + mWifiNetworkFactory.setWifiState(true); + assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest, 0)); + } + + /** + * Verify handling of new network request with network specifier when wifi is off. + */ + @Test + public void testHandleNetworkRequestWithSpecifierWhenWifiOff() { + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + + // set wifi off + mWifiNetworkFactory.setWifiState(false); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + verify(mWifiScanner, never()).startScan(any(), any(), any()); + + // set wifi on + mWifiNetworkFactory.setWifiState(true); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + verify(mWifiScanner).startScan(any(), any(), any()); + } + + /** + * Verify wifi toggle off when scanning. + */ + @Test + public void testHandleNetworkRequestWithSpecifierWifiOffWhenScanning() throws Exception { + WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1); + mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0); + + // Register callback. + mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback, + TEST_CALLBACK_IDENTIFIER); + verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(any()); + + verify(mWifiScanner).startScan(any(), any(), any()); + + // toggle wifi off & verify we aborted ongoing request. + mWifiNetworkFactory.setWifiState(false); + verify(mNetworkRequestMatchCallback).onAbort(); + verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false); + } + + /** + * Verify wifi toggle off after connection attempt is started. + */ + @Test + public void testHandleNetworkRequestWithSpecifierWifiOffAfterConnect() throws Exception { + sendNetworkRequestAndSetupForConnectionStatus(); + + // toggle wifi off & verify we aborted ongoing request. + mWifiNetworkFactory.setWifiState(false); + verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue()); + verify(mNetworkRequestMatchCallback).onAbort(); + verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false); + } + + /** + * Verify handling of new network request with network specifier when wifi is off & then on. + * Note: Unlike the other unit tests, this test invokes the top level + * {@link NetworkFactory#CMD_REQUEST_NETWORK} to simulate the full flow. + */ + @Test + public void testFullHandleNetworkRequestWithSpecifierWhenWifiOff() { + WifiNetworkSpecifier specifier = createWifiNetworkSpecifier(TEST_UID_1, false); + mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier); + + // set wifi off + mWifiNetworkFactory.setWifiState(false); + // Add the request, should do nothing. + Message message = Message.obtain(); + message.what = CMD_REQUEST_NETWORK; + message.obj = mNetworkRequest; + mWifiNetworkFactory.sendMessage(message); + mLooper.dispatchAll(); + verify(mWifiScanner, never()).startScan(any(), any(), any()); + + // set wifi on + mWifiNetworkFactory.setWifiState(true); + mLooper.dispatchAll(); + // Should trigger a re-evaluation of existing requests and the pending request will be + // processed now. + verify(mWifiScanner).startScan(any(), any(), any()); + } + + + // Helper method to setup the necessary pre-requisite steps for tracking connection status. private Messenger sendNetworkRequestAndSetupForConnectionStatus() throws RemoteException { when(mClock.getElapsedSinceBootMillis()).thenReturn(0L); |