summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/OpenNetworkNotifier.java43
-rw-r--r--service/java/com/android/server/wifi/OpenNetworkRecommender.java24
-rw-r--r--service/java/com/android/server/wifi/SsidSetStoreData.java131
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java2
-rw-r--r--tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java105
-rw-r--r--tests/wifitests/src/com/android/server/wifi/OpenNetworkRecommenderTest.java30
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java202
7 files changed, 469 insertions, 68 deletions
diff --git a/service/java/com/android/server/wifi/OpenNetworkNotifier.java b/service/java/com/android/server/wifi/OpenNetworkNotifier.java
index fc144c139..692c8e22c 100644
--- a/service/java/com/android/server/wifi/OpenNetworkNotifier.java
+++ b/service/java/com/android/server/wifi/OpenNetworkNotifier.java
@@ -29,6 +29,8 @@ import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.util.ArraySet;
+import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
@@ -36,18 +38,25 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.List;
+import java.util.Set;
/**
* Takes care of handling the "open wi-fi network available" notification
+ *
+ * NOTE: These API's are not thread safe and should only be used from WifiStateMachine thread.
* @hide
*/
public class OpenNetworkNotifier {
+ private static final String TAG = "OpenNetworkNotifier";
+
static final String ACTION_USER_DISMISSED_NOTIFICATION =
"com.android.server.wifi.OpenNetworkNotifier.USER_DISMISSED_NOTIFICATION";
static final String ACTION_USER_TAPPED_CONTENT =
"com.android.server.wifi.OpenNetworkNotifier.USER_TAPPED_CONTENT";
+ /** Identifier of the {@link SsidSetStoreData}. */
+ private static final String STORE_DATA_IDENTIFIER = "OpenNetworkNotifierBlacklist";
/**
* The {@link Clock#getWallClockMillis()} must be at least this value for us
* to show the notification again.
@@ -68,10 +77,14 @@ public class OpenNetworkNotifier {
/** Whether the screen is on or not. */
private boolean mScreenOn;
+ /** List of SSIDs blacklisted from recommendation. */
+ private final Set<String> mBlacklistedSsids;
+
private final Context mContext;
private final Handler mHandler;
private final FrameworkFacade mFrameworkFacade;
private final Clock mClock;
+ private final WifiConfigManager mConfigManager;
private final OpenNetworkRecommender mOpenNetworkRecommender;
private final OpenNetworkNotificationBuilder mOpenNetworkNotificationBuilder;
@@ -82,15 +95,22 @@ public class OpenNetworkNotifier {
Looper looper,
FrameworkFacade framework,
Clock clock,
+ WifiConfigManager wifiConfigManager,
+ WifiConfigStore wifiConfigStore,
OpenNetworkRecommender openNetworkRecommender) {
mContext = context;
mHandler = new Handler(looper);
mFrameworkFacade = framework;
mClock = clock;
+ mConfigManager = wifiConfigManager;
mOpenNetworkRecommender = openNetworkRecommender;
mOpenNetworkNotificationBuilder = new OpenNetworkNotificationBuilder(context, framework);
mScreenOn = false;
+ mBlacklistedSsids = new ArraySet<>();
+ wifiConfigStore.registerStoreData(new SsidSetStoreData(
+ STORE_DATA_IDENTIFIER, new OpenNetworkNotifierStoreData()));
+
// Setting is in seconds
mNotificationRepeatDelay = mFrameworkFacade.getIntegerSetting(context,
Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
@@ -165,7 +185,7 @@ public class OpenNetworkNotifier {
}
mRecommendedNetwork = mOpenNetworkRecommender.recommendNetwork(
- availableNetworks, mRecommendedNetwork);
+ availableNetworks, new ArraySet<>(mBlacklistedSsids));
postNotification(availableNetworks.size());
}
@@ -201,8 +221,14 @@ public class OpenNetworkNotifier {
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
- /** A delay is set before the next shown notification after user dismissal. */
private void handleUserDismissedAction() {
+ if (mRecommendedNetwork != null) {
+ // blacklist dismissed network
+ mBlacklistedSsids.add(mRecommendedNetwork.SSID);
+ mConfigManager.saveToStore(false /* forceWrite */);
+ Log.d(TAG, "Network is added to the open network notification blacklist: "
+ + mRecommendedNetwork.SSID);
+ }
mNotificationShown = false;
}
@@ -213,6 +239,19 @@ public class OpenNetworkNotifier {
pw.println("currentTime: " + mClock.getWallClockMillis());
pw.println("mNotificationRepeatTime: " + mNotificationRepeatTime);
pw.println("mNotificationShown: " + mNotificationShown);
+ pw.println("mBlacklistedSsids: " + mBlacklistedSsids.toString());
+ }
+
+ private class OpenNetworkNotifierStoreData implements SsidSetStoreData.DataSource {
+ @Override
+ public Set<String> getSsids() {
+ return new ArraySet<>(mBlacklistedSsids);
+ }
+
+ @Override
+ public void setSsids(Set<String> ssidList) {
+ mBlacklistedSsids.addAll(ssidList);
+ }
}
private class NotificationEnabledSettingObserver extends ContentObserver {
diff --git a/service/java/com/android/server/wifi/OpenNetworkRecommender.java b/service/java/com/android/server/wifi/OpenNetworkRecommender.java
index cd460e58b..5ceeddded 100644
--- a/service/java/com/android/server/wifi/OpenNetworkRecommender.java
+++ b/service/java/com/android/server/wifi/OpenNetworkRecommender.java
@@ -20,9 +20,12 @@ import android.annotation.NonNull;
import android.net.wifi.ScanResult;
import java.util.List;
+import java.util.Set;
/**
* Helps recommend the best available network for {@link OpenNetworkNotifier}.
+ *
+ * NOTE: These API's are not thread safe and should only be used from WifiStateMachine thread.
* @hide
*/
public class OpenNetworkRecommender {
@@ -32,31 +35,24 @@ public class OpenNetworkRecommender {
*
* @param networks List of scan details to pick a recommendation. This list should not be null
* or empty.
- * @param currentRecommendation The currently recommended network.
+ * @param blacklistedSsids The list of SSIDs that should not be recommended.
*/
- public ScanResult recommendNetwork(
- @NonNull List<ScanDetail> networks, ScanResult currentRecommendation) {
- ScanResult currentUpdatedRecommendation = null;
+ public ScanResult recommendNetwork(@NonNull List<ScanDetail> networks,
+ @NonNull Set<String> blacklistedSsids) {
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;
+
+ if (result != null && blacklistedSsids.contains(result.SSID)) {
+ result = null;
}
+ return result;
}
}
diff --git a/service/java/com/android/server/wifi/SsidSetStoreData.java b/service/java/com/android/server/wifi/SsidSetStoreData.java
new file mode 100644
index 000000000..daed26a6a
--- /dev/null
+++ b/service/java/com/android/server/wifi/SsidSetStoreData.java
@@ -0,0 +1,131 @@
+/*
+ * 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.text.TextUtils;
+
+import com.android.server.wifi.util.XmlUtil;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Store data for network notifiers.
+ *
+ * Below are the current configuration data for each respective store file:
+ *
+ * Share Store (system wide configurations)
+ * - No data
+ *
+ * User Store (user specific configurations)
+ * - Set of blacklisted SSIDs
+ */
+public class SsidSetStoreData implements WifiConfigStore.StoreData {
+ private static final String XML_TAG_SECTION_HEADER_SUFFIX = "ConfigData";
+ private static final String XML_TAG_SSID_SET = "SSIDSet";
+
+ private final String mTagName;
+ private final DataSource mDataSource;
+
+ /**
+ * Interface define the data source for the notifier store data.
+ */
+ public interface DataSource {
+ /**
+ * Retrieve the SSID set from the data source.
+ *
+ * @return Set of SSIDs
+ */
+ Set<String> getSsids();
+
+ /**
+ * Update the SSID set in the data source.
+ *
+ * @param ssidSet The set of SSIDs
+ */
+ void setSsids(Set<String> ssidSet);
+ }
+
+ /**
+ * Creates the SSID Set store data.
+ *
+ * @param name Identifier of the SSID set.
+ * @param dataSource The DataSource that implements the update and retrieval of the SSID set.
+ */
+ SsidSetStoreData(String name, DataSource dataSource) {
+ mTagName = name + XML_TAG_SECTION_HEADER_SUFFIX;
+ mDataSource = dataSource;
+ }
+
+ @Override
+ public void serializeData(XmlSerializer out, boolean shared)
+ throws XmlPullParserException, IOException {
+ if (shared) {
+ throw new XmlPullParserException("Share data not supported");
+ }
+ Set<String> ssidSet = mDataSource.getSsids();
+ if (ssidSet != null && !ssidSet.isEmpty()) {
+ XmlUtil.writeNextValue(out, XML_TAG_SSID_SET, mDataSource.getSsids());
+ }
+ }
+
+ @Override
+ public void deserializeData(XmlPullParser in, int outerTagDepth, boolean shared)
+ throws XmlPullParserException, IOException {
+ if (shared) {
+ throw new XmlPullParserException("Share data not supported");
+ }
+
+ while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
+ String[] valueName = new String[1];
+ Object value = XmlUtil.readCurrentValue(in, valueName);
+ if (TextUtils.isEmpty(valueName[0])) {
+ throw new XmlPullParserException("Missing value name");
+ }
+ switch (valueName[0]) {
+ case XML_TAG_SSID_SET:
+ mDataSource.setSsids((Set<String>) value);
+ break;
+ default:
+ throw new XmlPullParserException("Unknown tag under "
+ + mTagName + ": " + valueName[0]);
+ }
+ }
+ }
+
+ @Override
+ public void resetData(boolean shared) {
+ if (!shared) {
+ mDataSource.setSsids(new HashSet<>());
+ }
+ }
+
+ @Override
+ public String getName() {
+ return mTagName;
+ }
+
+ @Override
+ public boolean supportShareData() {
+ return false;
+ }
+}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 60c5d2fb9..26d702477 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -233,7 +233,7 @@ public class WifiInjector {
mCertManager = new WifiCertManager(mContext);
mOpenNetworkNotifier = new OpenNetworkNotifier(mContext,
mWifiStateMachineHandlerThread.getLooper(), mFrameworkFacade, mClock,
- new OpenNetworkRecommender());
+ mWifiConfigManager, mWifiConfigStore, new OpenNetworkRecommender());
mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService());
mWifiController = new WifiController(mContext, mWifiStateMachine, mSettingsStore,
mLockManager, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade);
diff --git a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
index 29c068ddc..957fc2294 100644
--- a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
@@ -37,6 +37,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.test.TestLooper;
import android.provider.Settings;
+import android.util.ArraySet;
import org.junit.Before;
import org.junit.Test;
@@ -47,6 +48,7 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
/**
* Unit tests for {@link OpenNetworkNotifier}.
@@ -60,6 +62,8 @@ public class OpenNetworkNotifierTest {
@Mock private Resources mResources;
@Mock private FrameworkFacade mFrameworkFacade;
@Mock private Clock mClock;
+ @Mock private WifiConfigStore mWifiConfigStore;
+ @Mock private WifiConfigManager mWifiConfigManager;
@Mock(answer = Answers.RETURNS_DEEP_STUBS) private Notification.Builder mNotificationBuilder;
@Mock private NotificationManager mNotificationManager;
@Mock private OpenNetworkRecommender mOpenNetworkRecommender;
@@ -67,6 +71,8 @@ public class OpenNetworkNotifierTest {
private OpenNetworkNotifier mNotificationController;
private BroadcastReceiver mBroadcastReceiver;
private ScanResult mDummyNetwork;
+ private List<ScanDetail> mOpenNetworks;
+ private Set<String> mBlacklistedSsids;
/** Initialize objects before each test run. */
@@ -90,11 +96,14 @@ public class OpenNetworkNotifierTest {
mDummyNetwork.capabilities = "[ESS]";
mDummyNetwork.level = MIN_RSSI_LEVEL;
when(mOpenNetworkRecommender.recommendNetwork(any(), any())).thenReturn(mDummyNetwork);
+ mOpenNetworks = new ArrayList<>();
+ mOpenNetworks.add(new ScanDetail(mDummyNetwork, null /* networkDetail */));
+ mBlacklistedSsids = new ArraySet<>();
TestLooper mock_looper = new TestLooper();
mNotificationController = new OpenNetworkNotifier(
- mContext, mock_looper.getLooper(), mFrameworkFacade,
- mClock, mOpenNetworkRecommender);
+ mContext, mock_looper.getLooper(), mFrameworkFacade, mClock, mWifiConfigManager,
+ mWifiConfigStore, mOpenNetworkRecommender);
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
verify(mContext).registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
@@ -102,20 +111,14 @@ public class OpenNetworkNotifierTest {
mNotificationController.handleScreenStateChanged(true);
}
- private List<ScanDetail> createOpenScanResults() {
- List<ScanDetail> scanResults = new ArrayList<>();
- scanResults.add(new ScanDetail(mDummyNetwork, null /* networkDetail */));
- return scanResults;
- }
-
/**
* When scan results with open networks are handled, a notification is posted.
*/
@Test
public void handleScanResults_hasOpenNetworks_notificationDisplayed() {
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
}
@@ -136,9 +139,9 @@ public class OpenNetworkNotifierTest {
*/
@Test
public void handleScanResults_notificationShown_emptyList_notificationCleared() {
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
mNotificationController.handleScanResults(new ArrayList<>());
@@ -151,9 +154,9 @@ public class OpenNetworkNotifierTest {
*/
@Test
public void handleScanResults_notificationShown_screenOff_emptyList_notificationCleared() {
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
mNotificationController.handleScreenStateChanged(false);
@@ -167,10 +170,10 @@ public class OpenNetworkNotifierTest {
*/
@Test
public void handleScanResults_notificationShowing_doesNotRepostNotification() {
- mNotificationController.handleScanResults(createOpenScanResults());
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
}
@@ -180,9 +183,9 @@ public class OpenNetworkNotifierTest {
*/
@Test
public void clearPendingNotification_clearsNotificationIfOneIsShowing() {
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
mNotificationController.clearPendingNotification(true);
@@ -208,7 +211,7 @@ public class OpenNetworkNotifierTest {
@Test
public void screenOff_handleScanResults_notificationNotDisplayed() {
mNotificationController.handleScreenStateChanged(false);
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
verify(mOpenNetworkRecommender, never()).recommendNetwork(any(), any());
verify(mNotificationManager, never()).notify(anyInt(), any());
@@ -220,17 +223,18 @@ public class OpenNetworkNotifierTest {
*/
@Test
public void postNotification_clearNotificationWithoutDelayReset_shouldNotPostNotification() {
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
mNotificationController.clearPendingNotification(false);
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
// Recommendation made twice but no new notification posted.
- verify(mOpenNetworkRecommender, times(2)).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender, times(2)).recommendNetwork(
+ mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
verify(mNotificationManager).cancel(anyInt());
}
@@ -241,16 +245,17 @@ public class OpenNetworkNotifierTest {
*/
@Test
public void postNotification_clearNotificationWithDelayReset_shouldPostNotification() {
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
mNotificationController.clearPendingNotification(true);
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender, times(2)).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender, times(2)).recommendNetwork(
+ mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager, times(2)).notify(anyInt(), any());
}
@@ -259,9 +264,9 @@ public class OpenNetworkNotifierTest {
*/
@Test
public void notificationTap_opensWifiSettings() {
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
mBroadcastReceiver.onReceive(
@@ -271,14 +276,37 @@ public class OpenNetworkNotifierTest {
}
/**
+ * When user dismissed notification and there is a recommended network, network ssid should be
+ * blacklisted.
+ */
+ @Test
+ public void userDismissedNotification_shouldBlacklistNetwork() {
+ mNotificationController.handleScanResults(mOpenNetworks);
+
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
+ verify(mNotificationManager).notify(anyInt(), any());
+
+ mBroadcastReceiver.onReceive(
+ mContext, new Intent(OpenNetworkNotifier.ACTION_USER_DISMISSED_NOTIFICATION));
+
+ verify(mWifiConfigManager).saveToStore(false /* forceWrite */);
+
+ mNotificationController.handleScanResults(mOpenNetworks);
+
+ Set<String> expectedBlacklist = new ArraySet<>();
+ expectedBlacklist.add(mDummyNetwork.SSID);
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, expectedBlacklist);
+ }
+
+ /**
* When a notification is posted and cleared without reseting delay, after the delay has passed
* the next scan with open networks should post a notification.
*/
@Test
public void delaySet_delayPassed_shouldPostNotification() {
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
mNotificationController.clearPendingNotification(false);
@@ -286,9 +314,10 @@ public class OpenNetworkNotifierTest {
// twice the delay time passed
when(mClock.getWallClockMillis()).thenReturn(DEFAULT_REPEAT_DELAY_SEC * 1000L * 2);
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender, times(2)).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender, times(2)).recommendNetwork(
+ mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager, times(2)).notify(anyInt(), any());
}
@@ -298,7 +327,7 @@ public class OpenNetworkNotifierTest {
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT))
.thenReturn(true);
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
verify(mOpenNetworkRecommender, never()).recommendNetwork(any(), any());
verify(mNotificationManager, never()).notify(anyInt(), any());
@@ -307,15 +336,15 @@ public class OpenNetworkNotifierTest {
/** Verifies that {@link UserManager#DISALLOW_CONFIG_WIFI} clears the showing notification. */
@Test
public void userHasDisallowConfigWifiRestriction_showingNotificationIsCleared() {
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
- verify(mOpenNetworkRecommender).recommendNetwork(any(), any());
+ verify(mOpenNetworkRecommender).recommendNetwork(mOpenNetworks, mBlacklistedSsids);
verify(mNotificationManager).notify(anyInt(), any());
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT))
.thenReturn(true);
- mNotificationController.handleScanResults(createOpenScanResults());
+ mNotificationController.handleScanResults(mOpenNetworks);
verify(mNotificationManager).cancel(anyInt());
}
diff --git a/tests/wifitests/src/com/android/server/wifi/OpenNetworkRecommenderTest.java b/tests/wifitests/src/com/android/server/wifi/OpenNetworkRecommenderTest.java
index becc1d2e8..720ec3797 100644
--- a/tests/wifitests/src/com/android/server/wifi/OpenNetworkRecommenderTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/OpenNetworkRecommenderTest.java
@@ -17,14 +17,18 @@
package com.android.server.wifi;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import android.net.wifi.ScanResult;
+import android.util.ArraySet;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
/**
* Tests for {@link OpenNetworkRecommender}.
@@ -36,10 +40,13 @@ public class OpenNetworkRecommenderTest {
private static final int MIN_RSSI_LEVEL = -127;
private OpenNetworkRecommender mOpenNetworkRecommender;
+ private Set<String> mBlacklistedSsids;
@Before
public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
mOpenNetworkRecommender = new OpenNetworkRecommender();
+ mBlacklistedSsids = new ArraySet<>();
}
private List<ScanDetail> createOpenScanResults(String... ssids) {
@@ -59,7 +66,8 @@ public class OpenNetworkRecommenderTest {
List<ScanDetail> scanResults = createOpenScanResults(TEST_SSID_1);
scanResults.get(0).getScanResult().level = MIN_RSSI_LEVEL;
- ScanResult actual = mOpenNetworkRecommender.recommendNetwork(scanResults, null);
+ ScanResult actual = mOpenNetworkRecommender.recommendNetwork(
+ scanResults, mBlacklistedSsids);
ScanResult expected = scanResults.get(0).getScanResult();
assertEquals(expected, actual);
}
@@ -71,28 +79,24 @@ public class OpenNetworkRecommenderTest {
scanResults.get(0).getScanResult().level = MIN_RSSI_LEVEL;
scanResults.get(1).getScanResult().level = MIN_RSSI_LEVEL + 1;
- ScanResult actual = mOpenNetworkRecommender.recommendNetwork(scanResults, null);
+ ScanResult actual = mOpenNetworkRecommender.recommendNetwork(
+ scanResults, mBlacklistedSsids);
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.
+ * If the best available open network is blacklisted, no networks should be recommended.
*/
@Test
- public void currentRecommendationHasEquallyHighRssi_shouldNotChangeRecommendation() {
+ public void blacklistBestNetworkSsid_shouldNeverRecommendNetwork() {
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;
+ scanResults.get(1).getScanResult().level = MIN_RSSI_LEVEL;
+ mBlacklistedSsids.add(TEST_SSID_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);
+ scanResults, mBlacklistedSsids);
+ assertNull(actual);
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
new file mode 100644
index 000000000..606b825ee
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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 static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.util.Xml;
+
+import com.android.internal.util.FastXmlSerializer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.SsidSetStoreData}.
+ */
+public class SsidSetStoreDataTest {
+ private static final String TEST_NOTIFIER_NAME = "TestNetwork";
+ private static final String TEST_SSID1 = "SSID 1";
+ private static final String TEST_SSID2 = "SSID 2";
+ private static final String TEST_SSID_SET_XML_STRING =
+ "<set name=\"SSIDSet\">\n"
+ + "<string>" + TEST_SSID1 + "</string>\n"
+ + "<string>" + TEST_SSID2 + "</string>\n"
+ + "</set>\n";
+ private static final byte[] TEST_SSID_SET_XML_BYTES =
+ TEST_SSID_SET_XML_STRING.getBytes(StandardCharsets.UTF_8);
+
+ @Mock SsidSetStoreData.DataSource mDataSource;
+ SsidSetStoreData mSsidSetStoreData;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mSsidSetStoreData = new SsidSetStoreData(TEST_NOTIFIER_NAME, mDataSource);
+ }
+
+ /**
+ * Helper function for serializing configuration data to a XML block.
+ *
+ * @param shared Flag indicating serializing shared or user configurations
+ * @return byte[] of the XML data
+ * @throws Exception
+ */
+ private byte[] serializeData(boolean shared) throws Exception {
+ final XmlSerializer out = new FastXmlSerializer();
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+ mSsidSetStoreData.serializeData(out, shared);
+ out.flush();
+ return outputStream.toByteArray();
+ }
+
+ /**
+ * Helper function for parsing configuration data from a XML block.
+ *
+ * @param data XML data to parse from
+ * @param shared Flag indicating parsing of shared or user configurations
+ * @throws Exception
+ */
+ private void deserializeData(byte[] data, boolean shared) throws Exception {
+ final XmlPullParser in = Xml.newPullParser();
+ final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
+ in.setInput(inputStream, StandardCharsets.UTF_8.name());
+ mSsidSetStoreData.deserializeData(in, in.getDepth(), shared);
+ }
+
+ /**
+ * Verify that a XmlPullParserException will be thrown when attempting to serialize data
+ * to the share store.
+ *
+ * @throws Exception
+ */
+ @Test(expected = XmlPullParserException.class)
+ public void serializeShareData() throws Exception {
+ serializeData(true /* shared */);
+ }
+
+ /**
+ * Verify that a XmlPullParserException will be thrown when attempting to deserialize
+ * data from the share store.
+ *
+ * @throws Exception
+ */
+ @Test(expected = XmlPullParserException.class)
+ public void deserializeShareData() throws Exception {
+ deserializeData(new byte[0], true /* shared */);
+ }
+
+ /**
+ * Verify that serializing the user store data without any configuration doesn't cause any
+ * crash and no data should be serialized.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void serializeEmptyConfigs() throws Exception {
+ when(mDataSource.getSsids()).thenReturn(new HashSet<String>());
+ assertEquals(0, serializeData(false /* shared */).length);
+ }
+
+ /**
+ * Verify that parsing an empty data doesn't cause any crash and no configuration should
+ * be deserialized.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void deserializeEmptyStoreData() throws Exception {
+ deserializeData(new byte[0], false /* shared */);
+ verify(mDataSource, never()).setSsids(any(Set.class));
+ }
+
+ /**
+ * Verify that {@link SsidSetStoreData} does not support share data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void supportShareData() throws Exception {
+ assertFalse(mSsidSetStoreData.supportShareData());
+ }
+
+ /**
+ * Verify that the store data is serialized correctly, matches the predefined test XML data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void serializeSsidSet() throws Exception {
+ Set<String> ssidSet = new HashSet<>();
+ ssidSet.add(TEST_SSID1);
+ ssidSet.add(TEST_SSID2);
+ when(mDataSource.getSsids()).thenReturn(ssidSet);
+ byte[] actualData = serializeData(false /* shared */);
+ assertTrue(Arrays.equals(TEST_SSID_SET_XML_BYTES, actualData));
+ }
+
+ /**
+ * Verify that the store data is deserialized correctly using the predefined test XML data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void deserializeSsidSet() throws Exception {
+ Set<String> ssidSet = new HashSet<>();
+ ssidSet.add(TEST_SSID1);
+ ssidSet.add(TEST_SSID2);
+ deserializeData(TEST_SSID_SET_XML_BYTES, false /* shared */);
+ verify(mDataSource).setSsids(eq(ssidSet));
+ }
+
+ /**
+ * Verify that a XmlPullParserException will be thrown when parsing a SSIDSet set with an
+ * unknown tag.
+ *
+ * @throws Exception
+ */
+ @Test(expected = XmlPullParserException.class)
+ public void parseSetWithUnknownTag() throws Exception {
+ String ssidSet =
+ "<set name=\"SSIDSet\">\n"
+ + "<string>" + TEST_SSID1 + "</string>\n"
+ + "<string>" + TEST_SSID2 + "</string>\n"
+ + "<Unknown>" + "badInput" + "</Unknown>" // Unknown tag.
+ + "</set>\n";
+ deserializeData(ssidSet.getBytes(StandardCharsets.UTF_8), false /* shared */);
+ }
+}