summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Chen <stewchen@google.com>2017-07-19 11:02:56 -0700
committerStephen Chen <stewchen@google.com>2017-08-14 11:36:39 -0700
commite699623dae17803bc8fb5dd56b3d6b17f64f9cc7 (patch)
tree6122edd5a70ac7d2ca84effdb26d7d53cea6295a
parentff14f546b406ead034c70d09381c6dadb9a0062d (diff)
ONA: Recommend a network using rssi strength.
This recommendation is not currently used to alter the existing functionality of ONA. It will be used when UI changes are made to surface and connect to the recommended network. Bug: 37357441 Bug: 37472257 Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: Ie3e640f6b3863f2640ea763aee3924cb76394933
-rw-r--r--service/java/com/android/server/wifi/OpenNetworkRecommender.java62
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java3
-rw-r--r--service/java/com/android/server/wifi/WifiNotificationController.java12
-rw-r--r--tests/wifitests/src/com/android/server/wifi/OpenNetworkRecommenderTest.java98
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNotificationControllerTest.java25
5 files changed, 193 insertions, 7 deletions
diff --git a/service/java/com/android/server/wifi/OpenNetworkRecommender.java b/service/java/com/android/server/wifi/OpenNetworkRecommender.java
new file mode 100644
index 000000000..44b4db0e0
--- /dev/null
+++ b/service/java/com/android/server/wifi/OpenNetworkRecommender.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import android.annotation.NonNull;
+import android.net.wifi.ScanResult;
+
+import java.util.List;
+
+/**
+ * Helps recommend the best available network for {@link WifiNotificationController}.
+ * @hide
+ */
+public class OpenNetworkRecommender {
+
+ /**
+ * Recommends the network with the best signal strength.
+ *
+ * @param networks List of scan details to pick a recommendation. This list should not be null
+ * or empty.
+ * @param currentRecommendation The currently recommended network.
+ */
+ public ScanResult recommendNetwork(
+ @NonNull List<ScanDetail> networks, ScanResult currentRecommendation) {
+ ScanResult currentUpdatedRecommendation = null;
+ ScanResult result = null;
+ int highestRssi = Integer.MIN_VALUE;
+ for (ScanDetail scanDetail : networks) {
+ ScanResult scanResult = scanDetail.getScanResult();
+
+ if (currentRecommendation != null
+ && currentRecommendation.SSID.equals(scanResult.SSID)) {
+ currentUpdatedRecommendation = scanResult;
+ }
+
+ if (scanResult.level > highestRssi) {
+ result = scanResult;
+ highestRssi = scanResult.level;
+ }
+ }
+ if (currentUpdatedRecommendation != null
+ && currentUpdatedRecommendation.level >= result.level) {
+ return currentUpdatedRecommendation;
+ } else {
+ return result;
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 241873824..0e769524b 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -232,7 +232,8 @@ public class WifiInjector {
new WrongPasswordNotifier(mContext, mFrameworkFacade));
mCertManager = new WifiCertManager(mContext);
mNotificationController = new WifiNotificationController(mContext,
- mWifiStateMachineHandlerThread.getLooper(), mFrameworkFacade, null);
+ mWifiStateMachineHandlerThread.getLooper(), mFrameworkFacade, null,
+ 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/WifiNotificationController.java b/service/java/com/android/server/wifi/WifiNotificationController.java
index 797fd438b..c226274a0 100644
--- a/service/java/com/android/server/wifi/WifiNotificationController.java
+++ b/service/java/com/android/server/wifi/WifiNotificationController.java
@@ -23,6 +23,7 @@ import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
+import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
@@ -81,15 +82,19 @@ public class WifiNotificationController {
private boolean mScreenOn;
private final Context mContext;
- private FrameworkFacade mFrameworkFacade;
+ private final FrameworkFacade mFrameworkFacade;
+ private final OpenNetworkRecommender mOpenNetworkRecommender;
+ private ScanResult mRecommendedNetwork;
WifiNotificationController(Context context,
Looper looper,
FrameworkFacade framework,
- Notification.Builder builder) {
+ Notification.Builder builder,
+ OpenNetworkRecommender recommender) {
mContext = context;
mFrameworkFacade = framework;
mNotificationBuilder = builder;
+ mOpenNetworkRecommender = recommender;
mScreenOn = false;
@@ -142,6 +147,9 @@ public class WifiNotificationController {
return;
}
+ mRecommendedNetwork = mOpenNetworkRecommender.recommendNetwork(
+ availableNetworks, mRecommendedNetwork);
+
setNotificationVisible(true, availableNetworks.size(), false, 0);
}
diff --git a/tests/wifitests/src/com/android/server/wifi/OpenNetworkRecommenderTest.java b/tests/wifitests/src/com/android/server/wifi/OpenNetworkRecommenderTest.java
new file mode 100644
index 000000000..becc1d2e8
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/OpenNetworkRecommenderTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import static org.junit.Assert.assertEquals;
+
+import android.net.wifi.ScanResult;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link OpenNetworkRecommender}.
+ */
+public class OpenNetworkRecommenderTest {
+
+ private static final String TEST_SSID_1 = "Test SSID 1";
+ private static final String TEST_SSID_2 = "Test SSID 2";
+ private static final int MIN_RSSI_LEVEL = -127;
+
+ private OpenNetworkRecommender mOpenNetworkRecommender;
+
+ @Before
+ public void setUp() throws Exception {
+ mOpenNetworkRecommender = new OpenNetworkRecommender();
+ }
+
+ private List<ScanDetail> createOpenScanResults(String... ssids) {
+ List<ScanDetail> scanResults = new ArrayList<>();
+ for (String ssid : ssids) {
+ ScanResult scanResult = new ScanResult();
+ scanResult.SSID = ssid;
+ scanResult.capabilities = "[ESS]";
+ scanResults.add(new ScanDetail(scanResult, null /* networkDetail */));
+ }
+ return scanResults;
+ }
+
+ /** If list of open networks contain only one network, that network should be returned. */
+ @Test
+ public void onlyNetworkIsRecommended() {
+ List<ScanDetail> scanResults = createOpenScanResults(TEST_SSID_1);
+ scanResults.get(0).getScanResult().level = MIN_RSSI_LEVEL;
+
+ ScanResult actual = mOpenNetworkRecommender.recommendNetwork(scanResults, null);
+ ScanResult expected = scanResults.get(0).getScanResult();
+ assertEquals(expected, actual);
+ }
+
+ /** Verifies that the network with the highest rssi is recommended. */
+ @Test
+ public void networkWithHighestRssiIsRecommended() {
+ List<ScanDetail> scanResults = createOpenScanResults(TEST_SSID_1, TEST_SSID_2);
+ scanResults.get(0).getScanResult().level = MIN_RSSI_LEVEL;
+ scanResults.get(1).getScanResult().level = MIN_RSSI_LEVEL + 1;
+
+ ScanResult actual = mOpenNetworkRecommender.recommendNetwork(scanResults, null);
+ ScanResult expected = scanResults.get(1).getScanResult();
+ assertEquals(expected, actual);
+ }
+
+ /**
+ * If the current recommended network is present in the list for the next recommendation and has
+ * an equal RSSI, the recommendation should not change.
+ */
+ @Test
+ public void currentRecommendationHasEquallyHighRssi_shouldNotChangeRecommendation() {
+ List<ScanDetail> scanResults = createOpenScanResults(TEST_SSID_1, TEST_SSID_2);
+ scanResults.get(0).getScanResult().level = MIN_RSSI_LEVEL + 1;
+ scanResults.get(1).getScanResult().level = MIN_RSSI_LEVEL + 1;
+
+ ScanResult currentRecommendation = new ScanResult(scanResults.get(1).getScanResult());
+ // next recommendation does not depend on the rssi of the input recommendation.
+ currentRecommendation.level = MIN_RSSI_LEVEL;
+
+ ScanResult expected = scanResults.get(1).getScanResult();
+ ScanResult actual = mOpenNetworkRecommender.recommendNetwork(
+ scanResults, currentRecommendation);
+ assertEquals(expected, actual);
+ }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNotificationControllerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNotificationControllerTest.java
index 27055a885..198cb669d 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNotificationControllerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNotificationControllerTest.java
@@ -46,12 +46,17 @@ import java.util.List;
*/
public class WifiNotificationControllerTest {
+ private static final String TEST_SSID_1 = "Test SSID 1";
+ private static final int MIN_RSSI_LEVEL = -127;
+
@Mock private Context mContext;
@Mock private Resources mResources;
@Mock private FrameworkFacade mFrameworkFacade;
@Mock private NotificationManager mNotificationManager;
+ @Mock private OpenNetworkRecommender mOpenNetworkRecommender;
@Mock private UserManager mUserManager;
private WifiNotificationController mNotificationController;
+ private ScanResult mDummyNetwork;
/** Initialize objects before each test run. */
@@ -65,19 +70,22 @@ public class WifiNotificationControllerTest {
when(mContext.getSystemService(Context.USER_SERVICE))
.thenReturn(mUserManager);
when(mContext.getResources()).thenReturn(mResources);
+ mDummyNetwork = new ScanResult();
+ mDummyNetwork.SSID = TEST_SSID_1;
+ mDummyNetwork.capabilities = "[ESS]";
+ mDummyNetwork.level = MIN_RSSI_LEVEL;
+ when(mOpenNetworkRecommender.recommendNetwork(any(), any())).thenReturn(mDummyNetwork);
TestLooper mock_looper = new TestLooper();
mNotificationController = new WifiNotificationController(
mContext, mock_looper.getLooper(), mFrameworkFacade,
- mock(Notification.Builder.class));
+ mock(Notification.Builder.class), mOpenNetworkRecommender);
mNotificationController.handleScreenStateChanged(true);
}
private List<ScanDetail> createOpenScanResults() {
List<ScanDetail> scanResults = new ArrayList<>();
- ScanResult scanResult = new ScanResult();
- scanResult.capabilities = "[ESS]";
- scanResults.add(new ScanDetail(scanResult, null /* networkDetail */));
+ scanResults.add(new ScanDetail(mDummyNetwork, null /* networkDetail */));
return scanResults;
}
@@ -88,6 +96,7 @@ public class WifiNotificationControllerTest {
public void handleScanResults_hasOpenNetworks_notificationDisplayed() {
mNotificationController.handleScanResults(createOpenScanResults());
+ verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
verify(mNotificationManager).notifyAsUser(any(), anyInt(), any(), any());
}
@@ -98,6 +107,7 @@ public class WifiNotificationControllerTest {
public void handleScanResults_emptyList_notificationNotDisplayed() {
mNotificationController.handleScanResults(new ArrayList<>());
+ verify(mOpenNetworkRecommender, never()).recommendNetwork(any(), any());
verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
}
@@ -109,6 +119,7 @@ public class WifiNotificationControllerTest {
public void handleScanResults_notificationShown_emptyList_notificationCleared() {
mNotificationController.handleScanResults(createOpenScanResults());
+ verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
verify(mNotificationManager).notifyAsUser(any(), anyInt(), any(), any());
mNotificationController.handleScanResults(new ArrayList<>());
@@ -123,6 +134,7 @@ public class WifiNotificationControllerTest {
public void handleScanResults_notificationShown_screenOff_emptyList_notificationCleared() {
mNotificationController.handleScanResults(createOpenScanResults());
+ verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
verify(mNotificationManager).notifyAsUser(any(), anyInt(), any(), any());
mNotificationController.handleScreenStateChanged(false);
@@ -139,6 +151,7 @@ public class WifiNotificationControllerTest {
mNotificationController.handleScanResults(createOpenScanResults());
mNotificationController.handleScanResults(createOpenScanResults());
+ verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
verify(mNotificationManager).notifyAsUser(any(), anyInt(), any(), any());
}
@@ -150,6 +163,7 @@ public class WifiNotificationControllerTest {
public void clearPendingNotification_clearsNotificationIfOneIsShowing() {
mNotificationController.handleScanResults(createOpenScanResults());
+ verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
verify(mNotificationManager).notifyAsUser(any(), anyInt(), any(), any());
mNotificationController.clearPendingNotification(true);
@@ -177,6 +191,7 @@ public class WifiNotificationControllerTest {
mNotificationController.handleScreenStateChanged(false);
mNotificationController.handleScanResults(createOpenScanResults());
+ verify(mOpenNetworkRecommender, never()).recommendNetwork(any(), any());
verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
}
@@ -188,6 +203,7 @@ public class WifiNotificationControllerTest {
mNotificationController.handleScanResults(createOpenScanResults());
+ verify(mOpenNetworkRecommender, never()).recommendNetwork(any(), any());
verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
}
@@ -196,6 +212,7 @@ public class WifiNotificationControllerTest {
public void userHasDisallowConfigWifiRestriction_showingNotificationIsCleared() {
mNotificationController.handleScanResults(createOpenScanResults());
+ verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
verify(mNotificationManager).notifyAsUser(any(), anyInt(), any(), any());
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT))