summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Chen <stewchen@google.com>2017-08-25 14:51:32 -0700
committerStephen Chen <stewchen@google.com>2017-09-06 14:33:53 -0700
commit08ffa580f6756129929667785408da377b363787 (patch)
treed771d80ad03eb3eadca6028d4da432ae6db7e970
parentb280c399d7be7d04a245c5fc2d2897f0ddc9cc0a (diff)
downloadandroid_frameworks_opt_net_wifi-08ffa580f6756129929667785408da377b363787.tar.gz
android_frameworks_opt_net_wifi-08ffa580f6756129929667785408da377b363787.tar.bz2
android_frameworks_opt_net_wifi-08ffa580f6756129929667785408da377b363787.zip
ONA: Implement connection attempt and failure callback.
Bug: 37357441 Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: I2d531304598249dcb18bdc45492e48ee90ddff5f
-rw-r--r--service/java/com/android/server/wifi/OpenNetworkNotifier.java66
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java11
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java3
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java5
-rw-r--r--tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java32
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java44
6 files changed, 146 insertions, 15 deletions
diff --git a/service/java/com/android/server/wifi/OpenNetworkNotifier.java b/service/java/com/android/server/wifi/OpenNetworkNotifier.java
index 692c8e22c..279223759 100644
--- a/service/java/com/android/server/wifi/OpenNetworkNotifier.java
+++ b/service/java/com/android/server/wifi/OpenNetworkNotifier.java
@@ -24,8 +24,12 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -34,6 +38,7 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.server.wifi.util.ScanResultUtil;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -54,6 +59,8 @@ public class OpenNetworkNotifier {
"com.android.server.wifi.OpenNetworkNotifier.USER_DISMISSED_NOTIFICATION";
static final String ACTION_USER_TAPPED_CONTENT =
"com.android.server.wifi.OpenNetworkNotifier.USER_TAPPED_CONTENT";
+ static final String ACTION_CONNECT_TO_NETWORK =
+ "com.android.server.wifi.OpenNetworkNotifier.CONNECT_TO_NETWORK";
/** Identifier of the {@link SsidSetStoreData}. */
private static final String STORE_DATA_IDENTIFIER = "OpenNetworkNotifierBlacklist";
@@ -85,6 +92,8 @@ public class OpenNetworkNotifier {
private final FrameworkFacade mFrameworkFacade;
private final Clock mClock;
private final WifiConfigManager mConfigManager;
+ private final WifiStateMachine mWifiStateMachine;
+ private final Messenger mSrcMessenger;
private final OpenNetworkRecommender mOpenNetworkRecommender;
private final OpenNetworkNotificationBuilder mOpenNetworkNotificationBuilder;
@@ -97,15 +106,18 @@ public class OpenNetworkNotifier {
Clock clock,
WifiConfigManager wifiConfigManager,
WifiConfigStore wifiConfigStore,
+ WifiStateMachine wifiStateMachine,
OpenNetworkRecommender openNetworkRecommender) {
mContext = context;
mHandler = new Handler(looper);
mFrameworkFacade = framework;
mClock = clock;
mConfigManager = wifiConfigManager;
+ mWifiStateMachine = wifiStateMachine;
mOpenNetworkRecommender = openNetworkRecommender;
mOpenNetworkNotificationBuilder = new OpenNetworkNotificationBuilder(context, framework);
mScreenOn = false;
+ mSrcMessenger = new Messenger(new Handler(looper, mConnectionStateCallback));
mBlacklistedSsids = new ArraySet<>();
wifiConfigStore.registerStoreData(new SsidSetStoreData(
@@ -122,6 +134,7 @@ public class OpenNetworkNotifier {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USER_DISMISSED_NOTIFICATION);
filter.addAction(ACTION_USER_TAPPED_CONTENT);
+ filter.addAction(ACTION_CONNECT_TO_NETWORK);
mContext.registerReceiver(
mBroadcastReceiver, filter, null /* broadcastPermission */, mHandler);
}
@@ -130,14 +143,38 @@ public class OpenNetworkNotifier {
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (ACTION_USER_TAPPED_CONTENT.equals(intent.getAction())) {
- handleUserClickedContentAction();
- } else if (ACTION_USER_DISMISSED_NOTIFICATION.equals(intent.getAction())) {
- handleUserDismissedAction();
+ switch (intent.getAction()) {
+ case ACTION_USER_TAPPED_CONTENT:
+ handleUserClickedContentAction();
+ break;
+ case ACTION_USER_DISMISSED_NOTIFICATION:
+ handleUserDismissedAction();
+ break;
+ case ACTION_CONNECT_TO_NETWORK:
+ handleConnectToNetworkAction();
+ break;
+ default:
+ Log.e(TAG, "Unknown action " + intent.getAction());
}
}
};
+ private final Handler.Callback mConnectionStateCallback = (Message msg) -> {
+ switch (msg.what) {
+ // Success here means that an attempt to connect to the network has been initiated.
+ // Successful connection updates are received via the
+ // WifiConnectivityManager#handleConnectionStateChanged() callback.
+ case WifiManager.CONNECT_NETWORK_SUCCEEDED:
+ break;
+ case WifiManager.CONNECT_NETWORK_FAILED:
+ handleConnectionFailure();
+ break;
+ default:
+ Log.e(TAG, "Unknown message " + msg.what);
+ }
+ return true;
+ };
+
/**
* Clears the pending notification. This is called by {@link WifiConnectivityManager} on stop.
*
@@ -213,6 +250,27 @@ public class OpenNetworkNotifier {
mNotificationRepeatTime = mClock.getWallClockMillis() + mNotificationRepeatDelay;
}
+ private void handleConnectToNetworkAction() {
+ if (mRecommendedNetwork == null) {
+ return;
+ }
+ Log.d(TAG, "User initiated connection to recommended network: " + mRecommendedNetwork.SSID);
+ WifiConfiguration network = ScanResultUtil.createNetworkFromScanResult(mRecommendedNetwork);
+ Message msg = Message.obtain();
+ msg.what = WifiManager.CONNECT_NETWORK;
+ msg.arg1 = WifiConfiguration.INVALID_NETWORK_ID;
+ msg.obj = network;
+ msg.replyTo = mSrcMessenger;
+ mWifiStateMachine.sendMessage(msg);
+ }
+
+ /**
+ * Handles when a Wi-Fi connection attempt failed.
+ */
+ public void handleConnectionFailure() {
+ // Stub. Should post connection failure notification once implemented.
+ }
+
/** Opens Wi-Fi picker. */
private void handleUserClickedContentAction() {
mNotificationShown = false;
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 9603357a1..a21c8473c 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -1086,6 +1086,17 @@ public class WifiConnectivityManager {
}
/**
+ * Handler when a WiFi connection attempt ended.
+ *
+ * @param failureCode {@link WifiMetrics.ConnectionEvent} failure code.
+ */
+ public void handleConnectionAttemptEnded(int failureCode) {
+ if (failureCode != WifiMetrics.ConnectionEvent.FAILURE_NONE) {
+ mOpenNetworkNotifier.handleConnectionFailure();
+ }
+ }
+
+ /**
* Handler when user toggles whether untrusted connection is allowed
*/
public void setUntrustedConnectionAllowed(boolean allowed) {
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 26d702477..a0d0e82d5 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -233,7 +233,8 @@ public class WifiInjector {
mCertManager = new WifiCertManager(mContext);
mOpenNetworkNotifier = new OpenNetworkNotifier(mContext,
mWifiStateMachineHandlerThread.getLooper(), mFrameworkFacade, mClock,
- mWifiConfigManager, mWifiConfigStore, new OpenNetworkRecommender());
+ mWifiConfigManager, mWifiConfigStore, mWifiStateMachine,
+ new OpenNetworkRecommender());
mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService());
mWifiController = new WifiController(mContext, mWifiStateMachine, mSettingsStore,
mLockManager, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade);
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index ce9c09432..90fb2f6e1 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -3425,11 +3425,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
}
/**
- * Inform other components (WifiMetrics, WifiDiagnostics, etc.) that the current connection attempt
- * has concluded.
+ * Inform other components (WifiMetrics, WifiDiagnostics, WifiConnectivityManager, etc.) that
+ * the current connection attempt has concluded.
*/
private void reportConnectionAttemptEnd(int level2FailureCode, int connectivityFailureCode) {
mWifiMetrics.endConnectionEvent(level2FailureCode, connectivityFailureCode);
+ mWifiConnectivityManager.handleConnectionAttemptEnded(level2FailureCode);
switch (level2FailureCode) {
case WifiMetrics.ConnectionEvent.FAILURE_NONE:
// Ideally, we'd wait until IP reachability has been confirmed. this code falls
diff --git a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
index 957fc2294..7c1223a79 100644
--- a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
@@ -33,6 +33,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.wifi.ScanResult;
+import android.os.Message;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.test.TestLooper;
@@ -66,6 +67,7 @@ public class OpenNetworkNotifierTest {
@Mock private WifiConfigManager mWifiConfigManager;
@Mock(answer = Answers.RETURNS_DEEP_STUBS) private Notification.Builder mNotificationBuilder;
@Mock private NotificationManager mNotificationManager;
+ @Mock private WifiStateMachine mWifiStateMachine;
@Mock private OpenNetworkRecommender mOpenNetworkRecommender;
@Mock private UserManager mUserManager;
private OpenNetworkNotifier mNotificationController;
@@ -103,7 +105,7 @@ public class OpenNetworkNotifierTest {
TestLooper mock_looper = new TestLooper();
mNotificationController = new OpenNetworkNotifier(
mContext, mock_looper.getLooper(), mFrameworkFacade, mClock, mWifiConfigManager,
- mWifiConfigStore, mOpenNetworkRecommender);
+ mWifiConfigStore, mWifiStateMachine, mOpenNetworkRecommender);
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
verify(mContext).registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
@@ -348,4 +350,32 @@ public class OpenNetworkNotifierTest {
verify(mNotificationManager).cancel(anyInt());
}
+
+ /**
+ * {@link OpenNetworkNotifier#ACTION_CONNECT_TO_NETWORK} does not connect to any network if
+ * there is no current recommendation.
+ */
+ @Test
+ public void actionConnectToNetwork_currentRecommendationIsNull_doesNothing() {
+ mBroadcastReceiver.onReceive(mContext,
+ new Intent(OpenNetworkNotifier.ACTION_CONNECT_TO_NETWORK));
+
+ verify(mWifiStateMachine, never()).sendMessage(any(Message.class));
+ }
+
+ /**
+ * {@link OpenNetworkNotifier#ACTION_CONNECT_TO_NETWORK} connects to the currently recommended
+ * network if it exists.
+ */
+ @Test
+ public void actionConnectToNetwork_currentRecommendationExists_connectsToNetwork() {
+ mNotificationController.handleScanResults(mOpenNetworks);
+
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
+
+ mBroadcastReceiver.onReceive(mContext,
+ new Intent(OpenNetworkNotifier.ACTION_CONNECT_TO_NETWORK));
+
+ verify(mWifiStateMachine).sendMessage(any(Message.class));
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
index a8278d365..cb1160cc1 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -614,7 +614,7 @@ public class WifiConnectivityManagerTest {
* Expected behavior: ONA handles scan results
*/
@Test
- public void wifiDisconnected_noConnectionCandidate_openNetworkNotificationScanResultsHandled() {
+ public void wifiDisconnected_noConnectionCandidate_openNetworkNotifierScanResultsHandled() {
// no connection candidate selected
when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
anyBoolean(), anyBoolean())).thenReturn(null);
@@ -643,12 +643,12 @@ public class WifiConnectivityManagerTest {
* Expected behavior: ONA clears pending notification and does not reset repeat delay.
*/
@Test
- public void wifiConnected_openNetworkNotificationClearsPendingNotification() {
+ public void wifiConnected_openNetworkNotifierClearsPendingNotification() {
// Set WiFi to connected state
mWifiConnectivityManager.handleConnectionStateChanged(
WifiConnectivityManager.WIFI_STATE_CONNECTED);
- verify(mOpenNetworkNotifier).clearPendingNotification(false /* isRepeatDelayReset*/);
+ verify(mOpenNetworkNotifier).clearPendingNotification(false /* resetRepeatDelay*/);
}
/**
@@ -658,7 +658,7 @@ public class WifiConnectivityManagerTest {
* Expected behavior: ONA does not clear pending notification.
*/
@Test
- public void wifiDisconnected_openNetworkNotificationDoesNotClearPendingNotification() {
+ public void wifiDisconnected_openNetworkNotifierDoesNotClearPendingNotification() {
// Set WiFi to disconnected state
mWifiConnectivityManager.handleConnectionStateChanged(
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
@@ -667,22 +667,52 @@ public class WifiConnectivityManagerTest {
}
/**
+ * When a Wi-Fi connection attempt ends, {@link OpenNetworkNotifier} handles the connection
+ * failure. A failure code that is not {@link WifiMetrics.ConnectionEvent#FAILURE_NONE}
+ * represents a connection failure.
+ *
+ * Expected behavior: ONA handles connection failure.
+ */
+ @Test
+ public void wifiConnectionEndsWithFailure_openNetworkNotifierHandlesConnectionFailure() {
+ mWifiConnectivityManager.handleConnectionAttemptEnded(
+ WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED);
+
+ verify(mOpenNetworkNotifier).handleConnectionFailure();
+ }
+
+ /**
+ * When a Wi-Fi connection attempt ends, {@link OpenNetworkNotifier} does not handle connection
+ * failure after a successful connection. {@link WifiMetrics.ConnectionEvent#FAILURE_NONE}
+ * represents a successful connection.
+ *
+ * Expected behavior: ONA does nothing.
+ */
+ @Test
+ public void wifiConnectionEndsWithSuccess_openNetworkNotifierDoesNotHandleConnectionFailure() {
+ mWifiConnectivityManager.handleConnectionAttemptEnded(
+ WifiMetrics.ConnectionEvent.FAILURE_NONE);
+
+ verify(mOpenNetworkNotifier, never()).handleConnectionFailure();
+ }
+
+ /**
* When Wi-Fi is disabled, clear the pending notification and reset notification repeat delay.
*
* Expected behavior: clear pending notification and reset notification repeat delay
* */
@Test
- public void openNetworkNotificationControllerToggledOnWifiStateChanges() {
+ public void openNetworkNotifierClearsPendingNotificationOnWifiDisabled() {
mWifiConnectivityManager.setWifiEnabled(false);
- verify(mOpenNetworkNotifier).clearPendingNotification(true /* isRepeatDelayReset */);
+ verify(mOpenNetworkNotifier).clearPendingNotification(true /* resetRepeatDelay */);
}
/**
* Verify that the ONA controller tracks screen state changes.
*/
@Test
- public void openNetworkNotificationControllerTracksScreenStateChanges() {
+ public void openNetworkNotifierTracksScreenStateChanges() {
mWifiConnectivityManager.handleScreenStateChanged(false);
verify(mOpenNetworkNotifier).handleScreenStateChanged(false);