summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java55
-rw-r--r--service/java/com/android/server/wifi/util/ExternalCallbackTracker.java10
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java154
3 files changed, 200 insertions, 19 deletions
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 1c1d5e57c..aaf2b2e6b 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -93,6 +93,7 @@ public class WifiNetworkFactory extends NetworkFactory {
// Verbose logging flag.
private boolean mVerboseLoggingEnabled = false;
private boolean mPeriodicScanTimerSet = false;
+ private boolean mConnectionTimeoutSet = false;
private boolean mIsConnectedToUserSelectedNetwork = false;
// Scan listener for scan requests.
@@ -365,6 +366,8 @@ public class WifiNetworkFactory extends NetworkFactory {
return;
}
retrieveWifiScanner();
+ // Reset state from any previous request.
+ resetStateForActiveRequestStart();
// Store the active network request.
mActiveSpecificNetworkRequest = new NetworkRequest(networkRequest);
@@ -408,11 +411,7 @@ public class WifiNetworkFactory extends NetworkFactory {
Log.e(TAG, "Network specifier does not match the active request. Ignoring");
return;
}
- if (mIsConnectedToUserSelectedNetwork) {
- Log.i(TAG, "Disconnecting from network on request release");
- mWifiInjector.getClientModeImpl().disconnectCommand();
- }
- resetState();
+ resetStateForActiveRequestEnd();
}
}
@@ -470,14 +469,12 @@ public class WifiNetworkFactory extends NetworkFactory {
mUserSelectedNetwork = network;
// Post an alarm to handle connection timeout.
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- mClock.getElapsedSinceBootMillis() + NETWORK_CONNECTION_TIMEOUT_MS,
- TAG, mConnectionTimeoutAlarmListener, mHandler);
+ scheduleConnectionTimeout();
}
private void handleRejectUserSelection() {
Log.w(TAG, "User dismissed notification");
- resetState();
+ resetStateForActiveRequestEnd();
}
private boolean isUserSelectedNetwork(WifiConfiguration config) {
@@ -522,7 +519,7 @@ public class WifiNetworkFactory extends NetworkFactory {
}
}
// Cancel connection timeout alarm.
- mAlarmManager.cancel(mConnectionTimeoutAlarmListener);
+ cancelConnectionTimeout();
// Set the connection status.
mIsConnectedToUserSelectedNetwork = true;
}
@@ -545,25 +542,39 @@ public class WifiNetworkFactory extends NetworkFactory {
+ callback, e);
}
}
- // Cancel any connection timeout alarm.
- mAlarmManager.cancel(mConnectionTimeoutAlarmListener);
- resetState();
+ resetStateForActiveRequestEnd();
}
private void resetState() {
+ if (mIsConnectedToUserSelectedNetwork) {
+ Log.i(TAG, "Disconnecting from network on reset");
+ mWifiInjector.getClientModeImpl().disconnectCommand();
+ }
// Reset the active network request.
mActiveSpecificNetworkRequest = null;
mActiveSpecificNetworkRequestSpecifier = null;
mUserSelectedNetwork = null;
mIsConnectedToUserSelectedNetwork = false;
cancelPeriodicScans();
- // Re-enable Auto-join.
- mWifiConnectivityManager.setSpecificNetworkRequestInProgress(false);
+ cancelConnectionTimeout();
+ // Remove any callbacks registered for the request.
+ mRegisteredCallbacks.clear();
// TODO(b/113878056): Force-release the network request to let the app know early that the
// attempt failed.
// TODO(b/113878056): End UI flow here.
}
+ // Invoked at the termination of previous active request processing.
+ private void resetStateForActiveRequestEnd() {
+ resetState();
+ mWifiConnectivityManager.setSpecificNetworkRequestInProgress(false);
+ }
+
+ // Invoked at the start of new active request processing.
+ private void resetStateForActiveRequestStart() {
+ resetState();
+ }
+
/**
* Check if the request comes from foreground app/service.
*/
@@ -707,5 +718,19 @@ public class WifiNetworkFactory extends NetworkFactory {
}
}
}
+
+ private void cancelConnectionTimeout() {
+ if (mConnectionTimeoutSet) {
+ mAlarmManager.cancel(mConnectionTimeoutAlarmListener);
+ mConnectionTimeoutSet = false;
+ }
+ }
+
+ private void scheduleConnectionTimeout() {
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ mClock.getElapsedSinceBootMillis() + NETWORK_CONNECTION_TIMEOUT_MS,
+ TAG, mConnectionTimeoutAlarmListener, mHandler);
+ mConnectionTimeoutSet = true;
+ }
}
diff --git a/service/java/com/android/server/wifi/util/ExternalCallbackTracker.java b/service/java/com/android/server/wifi/util/ExternalCallbackTracker.java
index 4bb846985..8f92da431 100644
--- a/service/java/com/android/server/wifi/util/ExternalCallbackTracker.java
+++ b/service/java/com/android/server/wifi/util/ExternalCallbackTracker.java
@@ -174,4 +174,14 @@ public class ExternalCallbackTracker<T> {
public int getNumCallbacks() {
return mCallbacks.size();
}
+
+ /**
+ * Remove all callbacks registered.
+ */
+ public void clear() {
+ for (ExternalCallbackHolder<T> externalCallback : mCallbacks.values()) {
+ externalCallback.reset();
+ }
+ mCallbacks.clear();
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index 6ef48557d..dfc31d9b2 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -110,6 +110,8 @@ public class WifiNetworkFactoryTest {
ArgumentCaptor.forClass(WorkSource.class);
ArgumentCaptor<INetworkRequestUserSelectionCallback> mNetworkRequestUserSelectionCallback =
ArgumentCaptor.forClass(INetworkRequestUserSelectionCallback.class);
+ ArgumentCaptor<OnAlarmListener> mPeriodicScanListenerArgumentCaptor =
+ ArgumentCaptor.forClass(OnAlarmListener.class);
ArgumentCaptor<OnAlarmListener> mConnectionTimeoutAlarmListenerArgumentCaptor =
ArgumentCaptor.forClass(OnAlarmListener.class);
@@ -1057,6 +1059,149 @@ public class WifiNetworkFactoryTest {
mWifiNetworkFactory.getActiveSpecificNetworkRequestUid(connectedNetwork));
}
+ /**
+ * Verify handling for new network request while processing another one.
+ */
+ @Test
+ public void testHandleNetworkRequestWithSpecifierWhenScanning() throws Exception {
+ WifiNetworkSpecifier specifier1 = createWifiNetworkSpecifier(TEST_UID_1, false);
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+
+ // Send second request.
+ WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+
+ verify(mWifiConnectivityManager, times(2)).setSpecificNetworkRequestInProgress(true);
+ verify(mWifiScanner, times(2)).startScan(any(), any(), any());
+
+ // Remove the stale request1 & ensure nothing happens.
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
+ mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
+
+ verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
+ mAlarmManager);
+
+ // Remove the active request2 & ensure auto-join is re-enabled.
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
+ mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
+
+ verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
+ }
+
+ /**
+ * Verify handling for new network request while processing another one.
+ */
+ @Test
+ public void testHandleNetworkRequestWithSpecifierAfterMatch() throws Exception {
+ sendNetworkRequestAndSetupForUserSelection();
+ WifiNetworkSpecifier specifier1 =
+ (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
+
+ INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
+ mNetworkRequestUserSelectionCallback.getValue();
+ assertNotNull(networkRequestUserSelectionCallback);
+
+ // Send second request.
+ WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+
+ // Ignore stale callbacks.
+ WifiConfiguration selectedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+ networkRequestUserSelectionCallback.select(selectedNetwork);
+ mLooper.dispatchAll();
+
+ verify(mWifiConnectivityManager, times(2)).setSpecificNetworkRequestInProgress(true);
+ verify(mWifiScanner, times(2)).startScan(any(), any(), any());
+ verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
+
+ // Remove the stale request1 & ensure nothing happens.
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
+ mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
+
+ verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
+ mAlarmManager);
+
+ // Remove the active request2 & ensure auto-join is re-enabled.
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
+ mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
+
+ verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
+ }
+
+ /**
+ * Verify handling for new network request while processing another one.
+ */
+ @Test
+ public void testHandleNetworkRequestWithSpecifierAfterConnect() throws Exception {
+ sendNetworkRequestAndSetupForConnectionStatus();
+ WifiNetworkSpecifier specifier1 =
+ (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
+
+ // Send second request.
+ WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+
+ verify(mWifiConnectivityManager, times(2)).setSpecificNetworkRequestInProgress(true);
+ verify(mWifiScanner, times(2)).startScan(any(), any(), any());
+ verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
+
+ // Remove the stale request1 & ensure nothing happens.
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
+ mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
+
+ verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
+ mAlarmManager);
+
+ // Remove the active request2 & ensure auto-join is re-enabled.
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
+ mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
+
+ verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
+ }
+
+ /**
+ * Verify handling for new network request while processing another one.
+ */
+ @Test
+ public void testHandleNetworkRequestWithSpecifierAfterConnectionSuccess() throws Exception {
+ sendNetworkRequestAndSetupForConnectionStatus();
+ WifiNetworkSpecifier specifier1 =
+ (WifiNetworkSpecifier) mNetworkRequest.networkCapabilities.getNetworkSpecifier();
+
+ // Send network connection success indication.
+ assertNotNull(mSelectedNetwork);
+ mWifiNetworkFactory.handleConnectionAttemptEnded(
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, mSelectedNetwork);
+
+ // Cancel the connection timeout.
+ verify(mAlarmManager).cancel(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
+
+ // Send second request.
+ WifiNetworkSpecifier specifier2 = createWifiNetworkSpecifier(TEST_UID_2, false);
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+
+ verify(mWifiConnectivityManager, times(2)).setSpecificNetworkRequestInProgress(true);
+ verify(mWifiScanner, times(2)).startScan(any(), any(), any());
+ verify(mClientModeImpl).disconnectCommand();
+
+ // Remove the stale request1 & ensure nothing happens.
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier1);
+ mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
+
+ verifyNoMoreInteractions(mWifiConnectivityManager, mWifiScanner, mClientModeImpl,
+ mAlarmManager);
+
+ // Remove the active request2 & ensure auto-join is re-enabled.
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier2);
+ mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
+
+ verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
+ }
// Helper method to setup the necessary pre-requisite steps for tracking connection status.
private Messenger sendNetworkRequestAndSetupForConnectionStatus() throws RemoteException {
@@ -1073,6 +1218,9 @@ public class WifiNetworkFactoryTest {
networkRequestUserSelectionCallback.select(mSelectedNetwork);
mLooper.dispatchAll();
+ // Cancel the periodic scan timer.
+ verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
+
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
verify(mClientModeImpl).sendMessage(messageCaptor.capture());
@@ -1126,8 +1274,6 @@ public class WifiNetworkFactoryTest {
private void verifyPeriodicScans(long...expectedIntervalsInSeconds) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
- ArgumentCaptor<OnAlarmListener> alarmListenerArgumentCaptor =
- ArgumentCaptor.forClass(OnAlarmListener.class);
OnAlarmListener alarmListener = null;
ArgumentCaptor<ScanListener> scanListenerArgumentCaptor =
ArgumentCaptor.forClass(ScanListener.class);
@@ -1154,8 +1300,8 @@ public class WifiNetworkFactoryTest {
inOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
eq(expectedNextIntervalInMs), any(),
- alarmListenerArgumentCaptor.capture(), any());
- alarmListener = alarmListenerArgumentCaptor.getValue();
+ mPeriodicScanListenerArgumentCaptor.capture(), any());
+ alarmListener = mPeriodicScanListenerArgumentCaptor.getValue();
assertNotNull(alarmListener);
}