diff options
author | Stephen Chen <stewchen@google.com> | 2017-08-08 17:55:21 -0700 |
---|---|---|
committer | Stephen Chen <stewchen@google.com> | 2017-09-05 11:40:23 -0700 |
commit | b280c399d7be7d04a245c5fc2d2897f0ddc9cc0a (patch) | |
tree | 7af445cadaed0b7bd6bfbb3584c18011d6534456 /tests | |
parent | 69fa2e7fa12b8f4c24a27b3291a0744cd808a324 (diff) |
ONA: Implement SSID blacklist handling for dismissed networks.
When ONA notifications are dismissed by the user, the recommended
network ssid is permanently blacklisted.
This change also removes the use of currentRecommendation in the
recommendation logic, because the extra stickiness is not neccesary due
to the slow scan rate that triggers a recommendation update.
Bug: 64091575
Bug: 37357441
Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: I27fc667ae51f9dbc4665ba9d15b18ed3e6daa058
Diffstat (limited to 'tests')
3 files changed, 286 insertions, 51 deletions
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 */); + } +} |