diff options
author | Joe LaPenna <jlapenna@google.com> | 2017-02-28 14:14:24 -0800 |
---|---|---|
committer | Joe LaPenna <jlapenna@google.com> | 2017-03-01 18:10:41 -0800 |
commit | 0ec2cba64094fe0964628a6ef8868cacfa73ce26 (patch) | |
tree | f90fca0651307fd5ed14d0bc2c63535d8c36bd99 | |
parent | d0448135be8de26949d56ee343145f854a0369a6 (diff) | |
download | NetworkRecommendation-0ec2cba64094fe0964628a6ef8868cacfa73ce26.tar.gz |
Update /wakeup/
Test: mma NetworkRecommendation RunNetworkRecommendationRoboTests
Bug: 34944625
Change-Id: Ie33a1f9462cc16408fd7ade092c5e0491c1d5ac3
15 files changed, 1509 insertions, 1070 deletions
diff --git a/robotests/src/com/android/networkrecommendation/TestUtil.java b/robotests/src/com/android/networkrecommendation/TestUtil.java deleted file mode 100644 index 747e081..0000000 --- a/robotests/src/com/android/networkrecommendation/TestUtil.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.networkrecommendation; - - - -/** - * This class is deprecated: Please add new test libraries to classes in the testlib tree. - * TODO(williamm): delete. - */ -@Deprecated -public class TestUtil { - - private TestUtil() {} // do not instantiate -} diff --git a/robotests/src/com/android/networkrecommendation/notify/WifiNotificationControllerTest.java b/robotests/src/com/android/networkrecommendation/notify/WifiNotificationControllerTest.java index 76766a3..6f918d9 100644 --- a/robotests/src/com/android/networkrecommendation/notify/WifiNotificationControllerTest.java +++ b/robotests/src/com/android/networkrecommendation/notify/WifiNotificationControllerTest.java @@ -412,6 +412,80 @@ public class WifiNotificationControllerTest { assertEquals(0, mRecommendationRequestCaptor.getValue().getScanResults().length); } + /** + * Test that recommendations are not requested for new scan results when user has clicked on + * connect and a notification is showing. + */ + @Test + public void verifyNotificationsFlowSkipNewScanResultsWhenConnectionAttempted() + throws Exception { + when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED); + + mBroadcastIntentTestHelper.sendWifiStateChanged(); + when(mNetworkInfo.getDetailedState()).thenReturn(DetailedState.DISCONNECTED); + mBroadcastIntentTestHelper.sendNetworkStateChanged(mNetworkInfo); + setOpenAccessPoints(); + createFakeBitmap(); + + when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class))) + .thenReturn(RecommendationResult.createConnectRecommendation(createFakeConfig())); + + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + verify(mNetworkRecommendationProvider, times(3)).requestRecommendation(any()); + + // Show main notification + verify(mWifiNotificationHelper) + .createMainNotification(any(WifiConfiguration.class), any(Bitmap.class)); + verify(mNotificationManager).notify(anyString(), anyInt(), any(Notification.class)); + + // Send connect intent, should attempt to connect to Wi-Fi + Intent intent = + new Intent(WifiNotificationController.ACTION_CONNECT_TO_RECOMMENDED_NETWORK); + ShadowApplication.getInstance().sendBroadcast(intent); + verify(mRoboCompatUtil).connectToWifi(any(WifiManager.class), any(WifiConfiguration.class)); + verify(mWifiNotificationHelper) + .createConnectingNotification(any(WifiConfiguration.class), any(Bitmap.class)); + verify(mNotificationManager, times(2)) + .notify(anyString(), anyInt(), any(Notification.class)); + + // No new recommendation requests made + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + verify(mNetworkRecommendationProvider, times(3)).requestRecommendation(any()); + } + + /** Test that the main notification updates when new scan results are available. */ + @Test + public void verifyNotificationsFlowUpdateMainNotificationOnNewScanResults() throws Exception { + when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED); + + mBroadcastIntentTestHelper.sendWifiStateChanged(); + when(mNetworkInfo.getDetailedState()).thenReturn(DetailedState.DISCONNECTED); + mBroadcastIntentTestHelper.sendNetworkStateChanged(mNetworkInfo); + setOpenAccessPoints(); + createFakeBitmap(); + + when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class))) + .thenReturn(RecommendationResult.createConnectRecommendation(createFakeConfig())); + + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + verify(mNetworkRecommendationProvider, times(3)).requestRecommendation(any()); + + // Show main notification + verify(mWifiNotificationHelper) + .createMainNotification(any(WifiConfiguration.class), any(Bitmap.class)); + verify(mNotificationManager).notify(anyString(), anyInt(), any(Notification.class)); + + // Update main notification. + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + verify(mNetworkRecommendationProvider, times(4)).requestRecommendation(any()); + verify(mNotificationManager, times(2)) + .notify(anyString(), anyInt(), any(Notification.class)); + } + /** Test dump() does not crash. */ @Test public void testDump() { diff --git a/robotests/src/com/android/networkrecommendation/wakeup/WifiWakeupControllerTest.java b/robotests/src/com/android/networkrecommendation/wakeup/WifiWakeupControllerTest.java new file mode 100644 index 0000000..d11cc43 --- /dev/null +++ b/robotests/src/com/android/networkrecommendation/wakeup/WifiWakeupControllerTest.java @@ -0,0 +1,520 @@ +/* + * 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.networkrecommendation.wakeup; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyList; +import static org.mockito.Matchers.anyMap; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import android.app.NotificationManager; +import android.content.ContentResolver; +import android.content.Intent; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiConfiguration.Status; +import android.net.wifi.WifiManager; +import android.os.Handler; +import android.os.PowerManager; +import android.provider.Settings; +import com.android.networkrecommendation.BroadcastIntentTestHelper; +import com.android.networkrecommendation.config.Flag; +import com.android.networkrecommendation.debug.WideAreaNetworks; +import com.android.networkrecommendation.util.RoboCompatUtil; +import com.google.common.collect.Lists; +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.io.StringWriter; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowApplication; +import org.robolectric.shadows.ShadowLooper; + +/** Unit tests for {@link WifiWakeupController}. */ +@RunWith(RobolectricTestRunner.class) +@Config(manifest = "packages/services/NetworkRecommendation/AndroidManifest.xml", sdk = 23) +public class WifiWakeupControllerTest { + private static final ScanResult OPEN_SCAN_RESULT = buildScanResult("ssid"); + private static final ScanResult SAVED_SCAN_RESULT = buildScanResult("ssid1"); + private static final ScanResult SAVED_SCAN_RESULT2 = buildScanResult("ssid2"); + private static final ScanResult SAVED_SCAN_RESULT_EXTERNAL = buildScanResult("ssid3"); + private static final ScanResult SAVED_SCAN_RESULT_WIDE_AREA = buildScanResult("xfinitywifi"); + + private static ScanResult buildScanResult(String ssid) { + try { + ScanResult scanResult = ScanResult.class.getConstructor().newInstance(); + scanResult.SSID = ssid; + return scanResult; + } catch (Exception e) { + return null; + } + } + + private ContentResolver mContentResolver; + @Mock private NotificationManager mNotificationManager; + @Mock private WifiWakeupNetworkSelector mWifiWakeupNetworkSelector; + @Mock private WifiWakeupHelper mWifiWakeupHelper; + @Mock private WifiManager mWifiManager; + @Mock private RoboCompatUtil mRoboCompatUtil; + @Mock private PowerManager mPowerManager; + + private WifiConfiguration mSavedWifiConfiguration; + private WifiConfiguration mSavedWifiConfiguration2; + private WifiConfiguration mSavedWifiConfigurationExternal; + private WifiConfiguration mSavedWifiConfigurationWideArea; + + private WifiWakeupController mWifiWakeupController; + private BroadcastIntentTestHelper mBroadcastIntentTestHelper; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + Flag.initForTest(); + RoboCompatUtil.setInstanceForTesting(mRoboCompatUtil); + + mSavedWifiConfiguration = new WifiConfiguration(); + mSavedWifiConfiguration.SSID = "\"" + SAVED_SCAN_RESULT.SSID + "\""; + mSavedWifiConfiguration.status = WifiConfiguration.Status.CURRENT; + mSavedWifiConfiguration2 = new WifiConfiguration(); + mSavedWifiConfiguration2.SSID = "\"" + SAVED_SCAN_RESULT2.SSID + "\""; + mSavedWifiConfiguration2.status = WifiConfiguration.Status.ENABLED; + mSavedWifiConfigurationExternal = new WifiConfiguration(); + mSavedWifiConfigurationExternal.SSID = "\"" + SAVED_SCAN_RESULT_EXTERNAL.SSID + "\""; + // TODO(netrec): why is this needed when this field is accessible when compiling the main apk? + // is robo_experimental behind backend_experimental? + when(mRoboCompatUtil.useExternalScores(mSavedWifiConfigurationExternal)).thenReturn(true); + mSavedWifiConfigurationExternal.status = WifiConfiguration.Status.ENABLED; + mSavedWifiConfigurationWideArea = new WifiConfiguration(); + mSavedWifiConfigurationWideArea.SSID = "\"" + SAVED_SCAN_RESULT_WIDE_AREA.SSID + "\""; + mSavedWifiConfigurationWideArea.status = WifiConfiguration.Status.ENABLED; + assertTrue(WideAreaNetworks.contains(SAVED_SCAN_RESULT_WIDE_AREA.SSID)); + + mContentResolver = RuntimeEnvironment.application.getContentResolver(); + Settings.Global.putInt(mContentResolver, Settings.Global.WIFI_WAKEUP_ENABLED, 1); + Settings.Global.putInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, 0); + when(mWifiManager.getWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_DISABLED); + ShadowLooper.resetThreadLoopers(); + + mWifiWakeupController = + new WifiWakeupController( + RuntimeEnvironment.application, + mContentResolver, + new Handler(ShadowLooper.getMainLooper()), + mWifiManager, + mPowerManager, + mWifiWakeupNetworkSelector, + mWifiWakeupHelper); + mWifiWakeupController.start(); + mBroadcastIntentTestHelper = new BroadcastIntentTestHelper(RuntimeEnvironment.application); + } + + /** + * When the NetworkRecommendationService associated with this WifiWakeupController is unbound, + * this WifiWakeupController should no longer function. + */ + @Test + public void wifiWakeupControllerStopped() { + mWifiWakeupController.stop(); + + assertFalse( + ShadowApplication.getInstance() + .hasReceiverForIntent( + new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))); + } + + /** + * When Wi-Fi is disabled and a saved network is in the scan list, and then this network is not + * in the scan list 3x, and then it is, Wi-Fi should be enabled. + */ + @Test + public void wifiEnabled_userDisabledWifiNearSavedNetwork_thenLeaves_thenMovesBack() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn(Lists.newArrayList(mSavedWifiConfiguration)); + when(mWifiManager.getScanResults()) + .thenReturn( + Lists.newArrayList(SAVED_SCAN_RESULT), + Lists.newArrayList(OPEN_SCAN_RESULT), + Lists.newArrayList(OPEN_SCAN_RESULT), + Lists.newArrayList(OPEN_SCAN_RESULT), + Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())) + .thenReturn(mSavedWifiConfiguration); + when(mWifiManager.getWifiState()) + .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED); + + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verify(mWifiManager, never()).setWifiEnabled(true); + + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verify(mWifiManager).setWifiEnabled(true); + verify(mWifiWakeupHelper).startWifiSession(mSavedWifiConfiguration); + } + + /** + * When Wi-Fi is disabled and a saved network is in the scan list, and then another scan result + * comes in 3x with only a different saved network, Wi-Fi should be enabled. + */ + @Test + public void wifiEnabled_userDisabledWifiNearSavedNetwork_thenMovesToAnotherSavedNetwork() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn(Lists.newArrayList(mSavedWifiConfiguration, mSavedWifiConfiguration2)); + when(mWifiManager.getScanResults()) + .thenReturn( + Lists.newArrayList(SAVED_SCAN_RESULT), + Lists.newArrayList(SAVED_SCAN_RESULT2)); + when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())) + .thenReturn(mSavedWifiConfiguration2); + when(mWifiManager.getWifiState()) + .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED); + + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + + verify(mWifiManager, never()).setWifiEnabled(true); + + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verify(mWifiManager).setWifiEnabled(true); + verify(mWifiWakeupHelper).startWifiSession(mSavedWifiConfiguration2); + } + + /** + * If Wi-Fi is disabled when a saved network is in the scan list, and then scan results come in + * for a saved wide area network 3x, Wi-Fi should not be enabled. + */ + @Test + public void wifiNotEnabled_userDisablesWifiNearSavedNetwork_thenMovesToWideAreaNetwork() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList( + mSavedWifiConfiguration, mSavedWifiConfigurationWideArea)); + when(mWifiManager.getScanResults()) + .thenReturn( + Lists.newArrayList(SAVED_SCAN_RESULT), + Lists.newArrayList(SAVED_SCAN_RESULT_WIDE_AREA)); + when(mWifiManager.getWifiState()) + .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED); + + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verifyZeroInteractions(mWifiWakeupNetworkSelector); + verify(mWifiManager, never()).setWifiEnabled(true); + } + + /** + * When Wi-Fi is enabled and a saved network is in the scan list, Wi-Fi should not be enabled. + */ + @Test + public void wifiNotEnabled_wifiAlreadyEnabled() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList( + mSavedWifiConfiguration, mSavedWifiConfigurationExternal)); + when(mWifiManager.getScanResults()).thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED); + + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verifyZeroInteractions(mWifiWakeupNetworkSelector); + verify(mWifiManager, never()).setWifiEnabled(true); + } + + /** + * When Wi-Fi is disabled and a saved network is in the scan list, but {@link + * WifiWakeupNetworkSelector}, does not choose this network, Wi-Fi should not be enabled. + */ + @Test + public void wifiNotEnabled_userNearSavedNetworkButNotSelected() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList( + mSavedWifiConfiguration, mSavedWifiConfigurationExternal)); + when(mWifiManager.getScanResults()).thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())).thenReturn(null); + when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); + + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verify(mWifiManager, never()).setWifiEnabled(true); + } + + /** + * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled if + * the user has not enabled the wifi wakeup feature. + */ + @Test + public void wifiNotEnabled_userDisablesWifiWakeupFeature() { + Settings.Global.putInt(mContentResolver, Settings.Global.WIFI_WAKEUP_ENABLED, 0); + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList( + mSavedWifiConfiguration, mSavedWifiConfigurationExternal)); + when(mWifiManager.getScanResults()).thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); + + mWifiWakeupController.mContentObserver.onChange(true); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verifyZeroInteractions(mWifiWakeupNetworkSelector); + verify(mWifiManager, never()).setWifiEnabled(true); + } + + /** + * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled if + * the user is in airplane mode. + */ + @Test + public void wifiNotEnabled_userIsInAirplaneMode() { + Settings.Global.putInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, 1); + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList( + mSavedWifiConfiguration, mSavedWifiConfigurationExternal)); + when(mWifiManager.getScanResults()).thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); + + mWifiWakeupController.mContentObserver.onChange(true); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verifyZeroInteractions(mWifiWakeupNetworkSelector); + verify(mWifiManager, never()).setWifiEnabled(true); + } + + /** + * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled if + * the wifi AP state is not disabled. + */ + @Test + public void wifiNotEnabled_wifiApStateIsNotDisabled() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList( + mSavedWifiConfiguration, mSavedWifiConfigurationExternal)); + when(mWifiManager.getScanResults()).thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); + when(mWifiManager.getWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_ENABLED); + + mWifiWakeupController.mContentObserver.onChange(true); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendWifiApStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verifyZeroInteractions(mWifiWakeupNetworkSelector); + verify(mWifiManager, never()).setWifiEnabled(true); + } + + /** + * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled if + * power saving mode is on. + */ + @Test + public void wifiNotEnabled_userInPowerSaveMode() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList( + mSavedWifiConfiguration, mSavedWifiConfigurationExternal)); + when(mWifiManager.getScanResults()).thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); + when(mPowerManager.isPowerSaveMode()).thenReturn(true); + + mWifiWakeupController.mContentObserver.onChange(true); + mBroadcastIntentTestHelper.sendPowerSaveModeChanged(); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendWifiApStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verifyZeroInteractions(mWifiWakeupNetworkSelector); + verify(mWifiManager, never()).setWifiEnabled(true); + } + + /** + * If Wi-Fi is disabled when a saved network is the scan list, Wi-Fi should not be enabled no + * matter how many scans are performed that include the saved network. + */ + @Test + public void wifiNotEnabled_userDisablesWifiNearSavedNetwork_thenDoesNotLeave() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList( + mSavedWifiConfiguration, mSavedWifiConfigurationExternal)); + when(mWifiManager.getScanResults()).thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); + + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verifyZeroInteractions(mWifiWakeupNetworkSelector); + verify(mWifiManager, never()).setWifiEnabled(true); + } + + /** + * If Wi-Fi is disabled when a saved network is in the scan list, and then that saved network is + * removed, Wi-Fi is not enabled even if the user leaves range of that network and returns. + */ + @Test + public void wifiNotEnabled_userDisablesWifiNearSavedNetwork_thenRemovesNetwork_thenStays() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList(mSavedWifiConfiguration), + Lists.<WifiConfiguration>newArrayList()); + when(mWifiManager.getScanResults()) + .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)) + .thenReturn(Lists.<ScanResult>newArrayList()) + .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())).thenReturn(null); + when(mWifiManager.getWifiState()) + .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED); + + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verify(mWifiManager, never()).setWifiEnabled(true); + } + + /** + * If Wi-Fi is disabled when 2 saved networks are in the scan list, and then a scan result comes + * in with only 1 saved network 3x, Wi-Fi should not be enabled. + */ + @Test + public void wifiNotEnabled_userDisablesWifiNear2SavedNetworks_thenLeavesRangeOfOneOfThem() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn(Lists.newArrayList(mSavedWifiConfiguration, mSavedWifiConfiguration2)); + when(mWifiManager.getScanResults()) + .thenReturn( + Lists.newArrayList(SAVED_SCAN_RESULT, SAVED_SCAN_RESULT2), + Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiManager.getWifiState()) + .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED); + + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + + verifyZeroInteractions(mWifiWakeupNetworkSelector); + verify(mWifiManager, never()).setWifiEnabled(true); + } + + @Test + public void logWifiEnabled_autopilotEnabledWifi() { + WifiConfiguration noInternetAccessNetwork = new WifiConfiguration(); + noInternetAccessNetwork.SSID = "Bof"; + when(mRoboCompatUtil.hasNoInternetAccess(noInternetAccessNetwork)).thenReturn(true); + + WifiConfiguration noInternetAccessExpectedNetwork = new WifiConfiguration(); + noInternetAccessExpectedNetwork.SSID = "fri"; + when(mRoboCompatUtil.isNoInternetAccessExpected(noInternetAccessExpectedNetwork)) + .thenReturn(true); + + WifiConfiguration disabledNetwork = new WifiConfiguration(); + disabledNetwork.SSID = "fleu"; + disabledNetwork.status = Status.DISABLED; + + WifiConfiguration noSsidNetwork = new WifiConfiguration(); + + when(mWifiManager.getConfiguredNetworks()) + .thenReturn( + Lists.newArrayList( + mSavedWifiConfiguration, + mSavedWifiConfiguration2, + mSavedWifiConfigurationExternal, + mSavedWifiConfigurationWideArea, + noInternetAccessNetwork, + noInternetAccessExpectedNetwork, + disabledNetwork, + noSsidNetwork)); + when(mWifiManager.getScanResults()).thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); + when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())) + .thenReturn(mSavedWifiConfiguration); + when(mWifiManager.getWifiState()) + .thenReturn(WifiManager.WIFI_STATE_DISABLED, WifiManager.WIFI_STATE_ENABLED); + + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + mBroadcastIntentTestHelper.sendScanResultsAvailable(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + + verify(mWifiManager).setWifiEnabled(true); + } + + @Test + public void logWifiEnabled_userEnabledWifi() { + when(mWifiManager.getConfiguredNetworks()) + .thenReturn(Lists.newArrayList(mSavedWifiConfiguration, mSavedWifiConfiguration2)); + when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED); + + mBroadcastIntentTestHelper.sendConfiguredNetworksChanged(); + mBroadcastIntentTestHelper.sendWifiStateChanged(); + } + + /** Test dump() does not crash. */ + @Test + public void testDump() { + StringWriter stringWriter = new StringWriter(); + mWifiWakeupController.dump( + new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); + } +} diff --git a/robotests/src/com/android/networkrecommendation/wakeup/WifiWakeupHelperTest.java b/robotests/src/com/android/networkrecommendation/wakeup/WifiWakeupHelperTest.java new file mode 100644 index 0000000..9c6cb80 --- /dev/null +++ b/robotests/src/com/android/networkrecommendation/wakeup/WifiWakeupHelperTest.java @@ -0,0 +1,159 @@ +/* + * 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.networkrecommendation.wakeup; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.Notification; +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.Handler; +import android.os.Looper; +import com.android.networkrecommendation.config.Flag; +import com.google.common.collect.ImmutableSet; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLooper; + +/** Unit tests for {@link WifiWakeupHelper} */ +@RunWith(RobolectricTestRunner.class) +@Config(manifest = "packages/services/NetworkRecommendation/AndroidManifest.xml", sdk = 23) +public class WifiWakeupHelperTest { + private static final String SSID = "ssid"; + + private Context mContext; + private WifiConfiguration mWifiConfiguration; + @Mock private NotificationManager mNotificationManager; + @Mock private WifiManager mWifiManager; + @Mock private WifiInfo mWifiInfo; + private SharedPreferences mSharedPreferences; + + private WifiWakeupHelper mWifiWakeupHelper; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + Flag.initForTest(); + mWifiConfiguration = new WifiConfiguration(); + mWifiConfiguration.SSID = "\"" + SSID + "\""; + + mContext = RuntimeEnvironment.application; + mSharedPreferences = mContext.getSharedPreferences("wifi_wakeup", Context.MODE_PRIVATE); + + when(mWifiManager.getConnectionInfo()).thenReturn(mWifiInfo); + + mWifiWakeupHelper = + new WifiWakeupHelper( + mContext, + mContext.getResources(), + new Handler(Looper.getMainLooper()), + mNotificationManager, + mWifiManager, + mSharedPreferences); + } + + @Test + public void notificationShowsOncePerSsid() { + mWifiWakeupHelper.startWifiSession(mWifiConfiguration); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); + + mWifiWakeupHelper.startWifiSession(mWifiConfiguration); + + verify(mNotificationManager, times(1)) + .notify(anyString(), anyInt(), any(Notification.class)); + Set<String> ssidSet = + mSharedPreferences.getStringSet(WifiWakeupHelper.KEY_SHOWN_SSIDS, null); + assertEquals(1, ssidSet.size()); + assertTrue(ssidSet.contains(mWifiConfiguration.SSID)); + } + + @Test + public void notificationCanceledWhenNeverConnected() { + mWifiWakeupHelper.startWifiSession(mWifiConfiguration); + + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); + + verify(mNotificationManager).cancel(anyString(), anyInt()); + } + + @Test + public void notificationCanceledWhenWifiDisabled() { + mWifiWakeupHelper.startWifiSession(mWifiConfiguration); + + when(mWifiInfo.getSSID()).thenReturn(SSID); + when(mWifiManager.isWifiEnabled()).thenReturn(true, false); + + mContext.sendBroadcast(new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); + mContext.sendBroadcast(new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); + + verify(mNotificationManager).cancel(anyString(), anyInt()); + } + + @Test + public void notificationCanceledWhenSsidChanged() throws Exception { + mWifiWakeupHelper.startWifiSession(mWifiConfiguration); + + when(mWifiInfo.getSSID()).thenReturn(SSID, "blah"); + when(mWifiManager.isWifiEnabled()).thenReturn(true); + + mContext.sendBroadcast(new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); + + verify(mNotificationManager, never()).cancel(anyString(), anyInt()); + + mContext.sendBroadcast(new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); + + verify(mNotificationManager).cancel(anyString(), anyInt()); + } + + @Test + public void sessionLoggedWithoutNotification() { + mSharedPreferences + .edit() + .putStringSet( + WifiWakeupHelper.KEY_SHOWN_SSIDS, ImmutableSet.of(mWifiConfiguration.SSID)) + .commit(); + when(mWifiInfo.getSSID()).thenReturn(SSID, "blah"); + when(mWifiManager.isWifiEnabled()).thenReturn(true); + + mWifiWakeupHelper.startWifiSession(mWifiConfiguration); + mContext.sendBroadcast(new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); + mContext.sendBroadcast(new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); + + verify(mNotificationManager, never()) + .notify(anyString(), anyInt(), any(Notification.class)); + verify(mNotificationManager, never()).cancel(anyString(), anyInt()); + } +} diff --git a/robotests/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelectorTest.java b/robotests/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelectorTest.java new file mode 100644 index 0000000..f48e3e4 --- /dev/null +++ b/robotests/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelectorTest.java @@ -0,0 +1,240 @@ +/* + * 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.networkrecommendation.wakeup; + +import static com.android.networkrecommendation.TestData.BSSID_3; +import static com.android.networkrecommendation.TestData.UNQUOTED_SSID_1; +import static com.android.networkrecommendation.TestData.UNQUOTED_SSID_2; +import static com.android.networkrecommendation.TestData.UNQUOTED_SSID_3; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.net.RecommendationRequest; +import android.net.RecommendationResult; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.util.ArrayMap; +import com.android.networkrecommendation.R; +import com.android.networkrecommendation.SynchronousNetworkRecommendationProvider; +import com.android.networkrecommendation.util.RoboCompatUtil; +import com.google.common.collect.Lists; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +/** Unit tests for {@link WifiWakeupNetworkSelector} */ +@RunWith(RobolectricTestRunner.class) +@Config(manifest = "packages/services/NetworkRecommendation/AndroidManifest.xml", sdk = 23) +public class WifiWakeupNetworkSelectorTest { + private static ScanResult buildScanResult(String ssid, int level, int frequency, String caps) { + try { + ScanResult scanResult = ScanResult.class.getConstructor().newInstance(); + scanResult.SSID = ssid; + scanResult.level = level; + scanResult.frequency = frequency; + scanResult.capabilities = caps; + return scanResult; + } catch (Exception e) { + return null; + } + } + + private static final int FREQUENCY_24 = 2450; + private static final int FREQUENCY_5 = 5000; + private static final String CAPABILITIES_NONE = ""; + private static final String CAPABILITIES_PSK = "PSK"; + + private WifiConfiguration mWifiConfigurationPsk; + private WifiConfiguration mWifiConfigurationNone; + private WifiConfiguration mWifiConfigurationPskExternal; + private ArrayMap<String, WifiConfiguration> mSavedWifiConfigurationMap; + private int mMinQualified24; + private int mMinQualified5; + + @Mock private RoboCompatUtil mRoboCompatUtil; + @Mock private SynchronousNetworkRecommendationProvider mNetworkRecommendationProvider; + @Captor private ArgumentCaptor<RecommendationRequest> mRecommendationRequestCaptor; + + private WifiWakeupNetworkSelector mWifiWakeupNetworkSelector; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + RoboCompatUtil.setInstanceForTesting(mRoboCompatUtil); + + mSavedWifiConfigurationMap = new ArrayMap<>(); + mWifiConfigurationPsk = new WifiConfiguration(); + mWifiConfigurationPsk.SSID = "\"" + UNQUOTED_SSID_1 + "\""; + mWifiConfigurationPsk.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + mSavedWifiConfigurationMap.put(UNQUOTED_SSID_1, mWifiConfigurationPsk); + + mWifiConfigurationNone = new WifiConfiguration(); + mWifiConfigurationNone.SSID = "\"" + UNQUOTED_SSID_2 + "\""; + mWifiConfigurationNone.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + mSavedWifiConfigurationMap.put(UNQUOTED_SSID_2, mWifiConfigurationNone); + + mWifiConfigurationPskExternal = new WifiConfiguration(); + mWifiConfigurationPskExternal.SSID = "\"" + UNQUOTED_SSID_3 + "\""; + mWifiConfigurationPskExternal.BSSID = BSSID_3; + mWifiConfigurationPskExternal.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + when(mRoboCompatUtil.useExternalScores(mWifiConfigurationPskExternal)).thenReturn(true); + mSavedWifiConfigurationMap.put(UNQUOTED_SSID_3, mWifiConfigurationPskExternal); + + mMinQualified24 = + RuntimeEnvironment.application + .getResources() + .getInteger(R.integer.config_netrec_wifi_score_low_rssi_threshold_24GHz); + mMinQualified5 = + RuntimeEnvironment.application + .getResources() + .getInteger(R.integer.config_netrec_wifi_score_low_rssi_threshold_5GHz); + + mWifiWakeupNetworkSelector = + new WifiWakeupNetworkSelector( + RuntimeEnvironment.application.getResources(), + mNetworkRecommendationProvider); + } + + @Test + public void testSelectNetwork_noSavedNetworksInScanResults() { + when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class))) + .thenReturn(RecommendationResult.createDoNotConnectRecommendation()); + List<ScanResult> scanResults = + Lists.newArrayList( + buildScanResult("blah", mMinQualified5 + 1, FREQUENCY_5, CAPABILITIES_NONE), + buildScanResult( + "blahtoo", mMinQualified24 + 1, FREQUENCY_24, CAPABILITIES_NONE)); + + WifiConfiguration selectedNetwork = + mWifiWakeupNetworkSelector.selectNetwork(mSavedWifiConfigurationMap, scanResults); + + assertNull(selectedNetwork); + verify(mNetworkRecommendationProvider, never()) + .requestRecommendation(any(RecommendationRequest.class)); + } + + @Test + public void testSelectNetwork_noQualifiedSavedNetworks() { + when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class))) + .thenReturn(RecommendationResult.createDoNotConnectRecommendation()); + List<ScanResult> scanResults = + Lists.newArrayList( + buildScanResult( + UNQUOTED_SSID_2, + mMinQualified5 - 1, + FREQUENCY_5, + CAPABILITIES_NONE), + buildScanResult( + UNQUOTED_SSID_2, + mMinQualified24 - 1, + FREQUENCY_24, + CAPABILITIES_NONE)); + + WifiConfiguration selectedNetwork = + mWifiWakeupNetworkSelector.selectNetwork(mSavedWifiConfigurationMap, scanResults); + + assertNull(selectedNetwork); + verify(mNetworkRecommendationProvider, never()) + .requestRecommendation(any(RecommendationRequest.class)); + } + + @Test + public void testSelectNetwork_noMatchingScanResults() { + when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class))) + .thenReturn(RecommendationResult.createDoNotConnectRecommendation()); + List<ScanResult> scanResults = + Lists.newArrayList( + buildScanResult( + UNQUOTED_SSID_1, + mMinQualified5 + 1, + FREQUENCY_5, + CAPABILITIES_NONE), + buildScanResult( + UNQUOTED_SSID_1, + mMinQualified24 + 1, + FREQUENCY_24, + CAPABILITIES_NONE)); + + WifiConfiguration selectedNetwork = + mWifiWakeupNetworkSelector.selectNetwork(mSavedWifiConfigurationMap, scanResults); + + assertNull(selectedNetwork); + verify(mNetworkRecommendationProvider, never()) + .requestRecommendation(any(RecommendationRequest.class)); + } + + @Test + public void testSelectNetwork_secureNetworkOverUnsecure() { + List<ScanResult> scanResults = + Lists.newArrayList( + buildScanResult( + UNQUOTED_SSID_1, mMinQualified5 + 1, FREQUENCY_5, CAPABILITIES_PSK), + buildScanResult( + UNQUOTED_SSID_2, + mMinQualified5 + 1, + FREQUENCY_5, + CAPABILITIES_NONE)); + + WifiConfiguration selectedNetwork = + mWifiWakeupNetworkSelector.selectNetwork(mSavedWifiConfigurationMap, scanResults); + + assertEquals(mWifiConfigurationPsk.networkId, selectedNetwork.networkId); + verify(mNetworkRecommendationProvider, never()) + .requestRecommendation(any(RecommendationRequest.class)); + } + + @Test + public void testSelectNetwork_deferToProviderForOpenAndUseExternalScores() { + when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class))) + .thenReturn( + RecommendationResult.createConnectRecommendation( + mWifiConfigurationPskExternal)); + List<ScanResult> scanResults = + Lists.newArrayList( + buildScanResult( + UNQUOTED_SSID_3, mMinQualified5 + 1, FREQUENCY_5, CAPABILITIES_PSK), + buildScanResult( + UNQUOTED_SSID_2, + mMinQualified5 + 1, + FREQUENCY_5, + CAPABILITIES_NONE)); + + WifiConfiguration selectedNetwork = + mWifiWakeupNetworkSelector.selectNetwork(mSavedWifiConfigurationMap, scanResults); + + assertEquals(mWifiConfigurationPskExternal, selectedNetwork); + verify(mNetworkRecommendationProvider) + .requestRecommendation(mRecommendationRequestCaptor.capture()); + + ScanResult[] openOrExternalScanResults = + mRecommendationRequestCaptor.getValue().getScanResults(); + assertEquals(2, openOrExternalScanResults.length); + assertEquals(UNQUOTED_SSID_3, openOrExternalScanResults[0].SSID); + assertEquals(UNQUOTED_SSID_2, openOrExternalScanResults[1].SSID); + } +} diff --git a/src/com/android/networkrecommendation/NetworkRecommendationService.java b/src/com/android/networkrecommendation/NetworkRecommendationService.java index 887741e..bf86c6c 100644 --- a/src/com/android/networkrecommendation/NetworkRecommendationService.java +++ b/src/com/android/networkrecommendation/NetworkRecommendationService.java @@ -27,12 +27,13 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; +import android.os.PowerManager; import com.android.networkrecommendation.notify.WifiNotificationController; import com.android.networkrecommendation.notify.WifiNotificationHelper; import com.android.networkrecommendation.wakeup.WifiWakeupController; +import com.android.networkrecommendation.wakeup.WifiWakeupHelper; import com.android.networkrecommendation.wakeup.WifiWakeupNetworkSelector; -import com.android.networkrecommendation.wakeup.WifiWakeupNotificationHelper; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -42,36 +43,43 @@ import java.io.PrintWriter; */ public class NetworkRecommendationService extends Service { - private HandlerThread mHandlerThread; - private Handler mHandler; + private HandlerThread mProviderHandlerThread; + private Handler mProviderHandler; + private HandlerThread mControllerHandlerThread; + private Handler mControllerHandler; private DefaultNetworkRecommendationProvider mProvider; private WifiNotificationController mWifiNotificationController; private WifiWakeupController mWifiWakeupController; @Override public void onCreate() { - mHandlerThread = new HandlerThread("RecommendationProvider"); - mHandlerThread.start(); - Looper looper = mHandlerThread.getLooper(); - mHandler = new Handler(looper); + mProviderHandlerThread = new HandlerThread("RecommendationProvider"); + mProviderHandlerThread.start(); + mProviderHandler = new Handler(mProviderHandlerThread.getLooper()); NetworkScoreManager networkScoreManager = getSystemService(NetworkScoreManager.class); - mProvider = new DefaultNetworkRecommendationProvider(this, mHandler::post, + mProvider = new DefaultNetworkRecommendationProvider(this, mProviderHandler::post, networkScoreManager, new DefaultNetworkRecommendationProvider.ScoreStorage()); + + mControllerHandlerThread = new HandlerThread("RecommendationProvider"); + mControllerHandlerThread.start(); + mControllerHandler = new Handler(mControllerHandlerThread.getLooper()); NotificationManager notificationManager = getSystemService(NotificationManager.class); WifiManager wifiManager = getSystemService(WifiManager.class); + PowerManager powerManager = getSystemService(PowerManager.class); Resources resources = getResources(); ContentResolver contentResolver = getContentResolver(); mWifiNotificationController = new WifiNotificationController( - this, contentResolver, new Handler(looper), mProvider, + this, contentResolver, mControllerHandler, mProvider, wifiManager, notificationManager, new WifiNotificationHelper(this, mProvider)); WifiWakeupNetworkSelector wifiWakeupNetworkSelector = - new WifiWakeupNetworkSelector(resources); - WifiWakeupNotificationHelper wifiWakeupNotificationHelper = - new WifiWakeupNotificationHelper(this, resources, new Handler(looper), - notificationManager, wifiManager); - mWifiWakeupController = new WifiWakeupController(this, contentResolver, looper, - wifiManager, wifiWakeupNetworkSelector, wifiWakeupNotificationHelper); + new WifiWakeupNetworkSelector(resources, mProvider); + WifiWakeupHelper wifiWakeupHelper = new WifiWakeupHelper(this, resources, mControllerHandler, + notificationManager, wifiManager); + mWifiWakeupController = + new WifiWakeupController(this, getContentResolver(), mControllerHandler, wifiManager, + getSystemService(PowerManager.class), wifiWakeupNetworkSelector, + wifiWakeupHelper); } @Override @@ -90,7 +98,7 @@ public class NetworkRecommendationService extends Service { @Override public void onDestroy() { - mHandlerThread.quit(); + mProviderHandlerThread.quit(); super.onDestroy(); } diff --git a/src/com/android/networkrecommendation/debug/WideAreaNetworks.java b/src/com/android/networkrecommendation/debug/WideAreaNetworks.java new file mode 100644 index 0000000..75330f3 --- /dev/null +++ b/src/com/android/networkrecommendation/debug/WideAreaNetworks.java @@ -0,0 +1,38 @@ +/* + * 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.networkrecommendation.debug; + +import com.google.common.collect.ImmutableSet; + +/** + * This class contains a list of known wide area netowrks. TODO(netrec): replace this with a flag + * value or a flag controlled bloom filter. + */ +public class WideAreaNetworks { + private WideAreaNetworks() {} + + /** + * @param ssid canonical SSID for a network (with quotes removed) + * @return {@code true} if {@code ssid} is in the set of wide area networks. + */ + public static final boolean contains(String ssid) { + return WIDE_AREA_NETWORK_SSIDS.contains(ssid); + } + + /** List of wide area networks. */ + private static final ImmutableSet<String> WIDE_AREA_NETWORK_SSIDS = + ImmutableSet.of("xfinitywifi"); +} diff --git a/src/com/android/networkrecommendation/notify/WifiNotificationController.java b/src/com/android/networkrecommendation/notify/WifiNotificationController.java index 459b547..3a0e31a 100644 --- a/src/com/android/networkrecommendation/notify/WifiNotificationController.java +++ b/src/com/android/networkrecommendation/notify/WifiNotificationController.java @@ -280,6 +280,7 @@ public class WifiNotificationController { // don't bother doing any of the following if (!mNotificationEnabled || mWifiState != WifiManager.WIFI_STATE_ENABLED + || mNotificationState > State.SHOWING_CONNECT_ACTIONS || scanResults == null || scanResults.isEmpty()) { return; @@ -381,7 +382,8 @@ public class WifiNotificationController { // place than here) // Not enough time has passed to show the notification again - if (System.currentTimeMillis() < mNotificationRepeatTime) { + if (mNotificationState == State.HIDDEN + && System.currentTimeMillis() < mNotificationRepeatTime) { return; } Notification notification = @@ -389,7 +391,9 @@ public class WifiNotificationController { mRecommendedNetwork, mNotificationBadgeBitmap); mNotificationRepeatTime = System.currentTimeMillis() + mNotificationRepeatDelayMs; postNotification(notification); - mNotificationState = State.SHOWING_CONNECT_ACTIONS; + if (mNotificationState != State.SHOWING_CONNECT_ACTIONS) { + mNotificationState = State.SHOWING_CONNECT_ACTIONS; + } } /** Opens activity to allow the user to select a wifi network. */ diff --git a/src/com/android/networkrecommendation/wakeup/WifiWakeupController.java b/src/com/android/networkrecommendation/wakeup/WifiWakeupController.java index 79d5475..ecd47bf 100644 --- a/src/com/android/networkrecommendation/wakeup/WifiWakeupController.java +++ b/src/com/android/networkrecommendation/wakeup/WifiWakeupController.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.android.networkrecommendation.wakeup; +import static com.android.networkrecommendation.Constants.TAG; + import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -26,16 +27,17 @@ 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.PowerManager; import android.provider.Settings; import android.support.annotation.VisibleForTesting; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; - +import com.android.networkrecommendation.config.G; +import com.android.networkrecommendation.debug.WideAreaNetworks; import com.android.networkrecommendation.util.Blog; +import com.android.networkrecommendation.util.RoboCompatUtil; import com.android.networkrecommendation.util.WifiConfigurationUtil; - import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.List; @@ -46,27 +48,24 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * Handles enabling Wi-Fi for the Wi-Fi Wakeup feature. * - * <p> - * This class enables Wi-Fi when the user is near a network that would would autojoined if Wi-Fi - * were enabled. When a user disables Wi-Fi, Wi-Fi Wakeup will not enable Wi-Fi until the - * user's context has changed. For saved networks, this context change is defined by the user - * leaving the range of the saved SSIDs that were in range when the user disabled Wi-Fi. + * <p>This class enables Wi-Fi when the user is near a network that would would autojoined if Wi-Fi + * were enabled. When a user disables Wi-Fi, Wi-Fi Wakeup will not enable Wi-Fi until the user's + * context has changed. For saved networks, this context change is defined by the user leaving the + * range of the saved SSIDs that were in range when the user disabled Wi-Fi. * * @hide */ public class WifiWakeupController { - private static final String TAG = "WifiWakeupController"; - /** Number of scans to ensure that a previously in range AP is now out of range. */ private static final int NUM_SCANS_TO_CONFIRM_AP_LOSS = 3; private final Context mContext; private final ContentResolver mContentResolver; private final WifiManager mWifiManager; + private final PowerManager mPowerManager; private final WifiWakeupNetworkSelector mWifiWakeupNetworkSelector; private final Handler mHandler; - private final WifiWakeupNotificationHelper mWifiWakeupNotificationHelper; - private final SettingsFacade mSettingsFacade; + private final WifiWakeupHelper mWifiWakeupHelper; private final AtomicBoolean mStarted; @VisibleForTesting final ContentObserver mContentObserver; @@ -74,60 +73,74 @@ public class WifiWakeupController { private final Set<String> mSavedSsidsInLastScan = new ArraySet<>(); private final Set<String> mSavedSsids = new ArraySet<>(); private final Map<String, Integer> mSavedSsidsOnDisable = new ArrayMap<>(); + private final SavedNetworkCounts mSavedNetworkCounts = new SavedNetworkCounts(); private int mWifiState; private int mWifiApState; private boolean mWifiWakeupEnabled; private boolean mAirplaneModeEnabled; + private boolean mAutopilotEnabledWifi; + private boolean mPowerSaverModeOn; - public WifiWakeupController(Context context, ContentResolver contentResolver, Looper looper, - WifiManager wifiManager, WifiWakeupNetworkSelector wifiWakeupNetworkSelector, - WifiWakeupNotificationHelper wifiWakeupNotificationHelper) { - this(context, contentResolver, looper, wifiManager, wifiWakeupNetworkSelector, - wifiWakeupNotificationHelper, new SettingsFacade()); - } - - @VisibleForTesting - WifiWakeupController(Context context, ContentResolver contentResolver, Looper looper, - WifiManager wifiManager, WifiWakeupNetworkSelector wifiWakeupNetworkSelector, - WifiWakeupNotificationHelper wifiWakeupNotificationHelper, - SettingsFacade settingsFacade) { + public WifiWakeupController( + Context context, + ContentResolver contentResolver, + Handler handler, + WifiManager wifiManager, + PowerManager powerManager, + WifiWakeupNetworkSelector wifiWakeupNetworkSelector, + WifiWakeupHelper wifiWakeupHelper) { mContext = context; mContentResolver = contentResolver; - mHandler = new Handler(looper); - mWifiWakeupNotificationHelper = wifiWakeupNotificationHelper; - mSettingsFacade = settingsFacade; + mHandler = handler; + mWifiWakeupHelper = wifiWakeupHelper; mStarted = new AtomicBoolean(false); mWifiManager = wifiManager; + mPowerManager = powerManager; mWifiWakeupNetworkSelector = wifiWakeupNetworkSelector; - mContentObserver = new ContentObserver(mHandler) { - @Override - public void onChange(boolean selfChange) { - mWifiWakeupEnabled = mSettingsFacade.getInt(mContentResolver, - Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1; - mAirplaneModeEnabled = mSettingsFacade.getInt(mContentResolver, - Settings.Global.AIRPLANE_MODE_ON, 0) == 1; - } - }; + mContentObserver = + new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange) { + mWifiWakeupEnabled = + Settings.Global.getInt( + mContentResolver, + Settings.Global.WIFI_WAKEUP_ENABLED, + 0) + == 1; + mAirplaneModeEnabled = + Settings.Global.getInt( + mContentResolver, + Settings.Global.AIRPLANE_MODE_ON, + 0) + == 1; + } + }; } - private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (!mWifiWakeupEnabled) { - return; - } + private final BroadcastReceiver mBroadcastReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (!mWifiWakeupEnabled) { + return; + } - if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) { - handleWifiApStateChanged(); - } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) { - handleWifiStateChanged(); - } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) { - handleScanResultsAvailable(); - } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(intent.getAction())) { - handleConfiguredNetworksChanged(); - } - } - }; + if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) { + handleWifiApStateChanged(); + } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) { + handleWifiStateChanged(); + } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals( + intent.getAction())) { + handleScanResultsAvailable(); + } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals( + intent.getAction())) { + handleConfiguredNetworksChanged(); + } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals( + intent.getAction())) { + handlePowerSaverModeChanged(); + } + } + }; /** Starts {@link WifiWakeupController}. */ public void start() { @@ -135,19 +148,26 @@ public class WifiWakeupController { return; } Blog.d(TAG, "Starting WifiWakeupController."); + IntentFilter filter = new IntentFilter(); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); filter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); + filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); // TODO(b/33695273): conditionally register this receiver based on wifi enabled setting mContext.registerReceiver(mBroadcastReceiver, filter, null, mHandler); - mContentResolver.registerContentObserver(Settings.Global.getUriFor( - Settings.Global.WIFI_WAKEUP_ENABLED), true, mContentObserver); - mContentResolver.registerContentObserver(Settings.Global.getUriFor( - Settings.Global.AIRPLANE_MODE_ON), true, mContentObserver); + mContentResolver.registerContentObserver( + Settings.Global.getUriFor(Settings.Global.WIFI_WAKEUP_ENABLED), + true, + mContentObserver); + mContentResolver.registerContentObserver( + Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), + true, + mContentObserver); mContentObserver.onChange(true); handleWifiStateChanged(); + handlePowerSaverModeChanged(); handleWifiApStateChanged(); handleConfiguredNetworksChanged(); handleScanResultsAvailable(); @@ -163,9 +183,14 @@ public class WifiWakeupController { mContentResolver.unregisterContentObserver(mContentObserver); } + private void handlePowerSaverModeChanged() { + mPowerSaverModeOn = mPowerManager.isPowerSaveMode(); + Blog.v(TAG, "handlePowerSaverModeChanged: %b", mPowerSaverModeOn); + } + private void handleWifiApStateChanged() { mWifiApState = mWifiManager.getWifiApState(); - Blog.v(TAG, "handleWifiApStateChanged: " + mWifiApState); + Blog.v(TAG, "handleWifiApStateChanged: %d", mWifiApState); } private void handleConfiguredNetworksChanged() { @@ -173,8 +198,10 @@ public class WifiWakeupController { if (wifiConfigurations == null) { return; } - Blog.v(TAG, "handleConfiguredNetworksChanged: " + wifiConfigurations.size()); + Blog.v(TAG, "handleConfiguredNetworksChanged: %d", wifiConfigurations.size()); + mSavedNetworkCounts.clear(); + mSavedNetworkCounts.total = wifiConfigurations.size(); mSavedNetworks.clear(); mSavedSsids.clear(); for (int i = 0; i < wifiConfigurations.size(); i++) { @@ -183,35 +210,54 @@ public class WifiWakeupController { && wifiConfiguration.status != WifiConfiguration.Status.CURRENT) { continue; // Ignore networks that are not connected or enabled. } - if (wifiConfiguration.useExternalScores) { - continue; // Ignore externally scored networks. + mSavedNetworkCounts.enabled++; + if (RoboCompatUtil.getInstance().hasNoInternetAccess(wifiConfiguration)) { + mSavedNetworkCounts.noInternetAccess++; + continue; // Ignore networks that do not have verified internet access. } - if (wifiConfiguration.hasNoInternetAccess() - || wifiConfiguration.isNoInternetAccessExpected()) { - continue; // Ignore networks that will likely not have internet access. + if (RoboCompatUtil.getInstance().isNoInternetAccessExpected(wifiConfiguration)) { + mSavedNetworkCounts.noInternetAccessExpected++; + continue; // Ignore networks that are expected not to have internet access. } String ssid = WifiConfigurationUtil.removeDoubleQuotes(wifiConfiguration); if (TextUtils.isEmpty(ssid)) { continue; } + if (WideAreaNetworks.contains(ssid)) { + mSavedNetworkCounts.blacklisted++; + continue; // Ignore wide area networks. + } mSavedNetworks.put(ssid, wifiConfiguration); mSavedSsids.add(ssid); + + if (WifiConfigurationUtil.isConfigForOpenNetwork(wifiConfiguration)) { + mSavedNetworkCounts.open++; + } + if (RoboCompatUtil.getInstance().useExternalScores(wifiConfiguration)) { + mSavedNetworkCounts.useExternalScores++; + } } mSavedSsidsInLastScan.retainAll(mSavedSsids); } private void handleWifiStateChanged() { mWifiState = mWifiManager.getWifiState(); - Blog.v(TAG, "handleWifiStateChanged: " + mWifiState); + Blog.v(TAG, "handleWifiStateChanged: %d", mWifiState); + switch (mWifiState) { case WifiManager.WIFI_STATE_ENABLED: mSavedSsidsOnDisable.clear(); + if (!mAutopilotEnabledWifi) {} break; case WifiManager.WIFI_STATE_DISABLED: for (String ssid : mSavedSsidsInLastScan) { mSavedSsidsOnDisable.put(ssid, NUM_SCANS_TO_CONFIRM_AP_LOSS); } + Blog.d(TAG, "Disabled ssid set: %s", mSavedSsidsOnDisable); + + mAutopilotEnabledWifi = false; break; + default: // Only handle ENABLED and DISABLED states } } @@ -220,7 +266,7 @@ public class WifiWakeupController { if (scanResults == null) { return; } - Blog.v(TAG, "handleScanResultsAvailable: " + scanResults.size()); + Blog.v(TAG, "handleScanResultsAvailable: %d", scanResults.size()); mSavedSsidsInLastScan.clear(); for (int i = 0; i < scanResults.size(); i++) { @@ -232,7 +278,8 @@ public class WifiWakeupController { if (mAirplaneModeEnabled || mWifiState != WifiManager.WIFI_STATE_DISABLED - || mWifiApState != WifiManager.WIFI_AP_STATE_DISABLED) { + || mWifiApState != WifiManager.WIFI_AP_STATE_DISABLED + || mPowerSaverModeOn) { return; } @@ -250,21 +297,32 @@ public class WifiWakeupController { } if (!mSavedSsidsOnDisable.isEmpty()) { - Blog.d(TAG, "Latest scan result contains ssids from the disabled set: " - + mSavedSsidsOnDisable); + Blog.d( + TAG, + "Scan results contain ssids from the disabled set: %s", + mSavedSsidsOnDisable); + return; + } + + if (mSavedSsidsInLastScan.isEmpty()) { + Blog.v(TAG, "Scan results do not contain any saved ssids."); return; } - WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector.selectNetwork(mSavedNetworks, - scanResults); + WifiConfiguration selectedNetwork = + mWifiWakeupNetworkSelector.selectNetwork(mSavedNetworks, scanResults); if (selectedNetwork != null) { - Blog.d(TAG, "Enabling wifi for ssid: " + selectedNetwork.SSID); + Blog.d( + TAG, + "Enabling wifi for ssid: %s", + Blog.pii(selectedNetwork.SSID, G.Netrec.enableSensitiveLogging.get())); + + mAutopilotEnabledWifi = true; mWifiManager.setWifiEnabled(true /* enabled */); - mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(selectedNetwork); + mWifiWakeupHelper.startWifiSession(selectedNetwork); } } - /** Dump debugging information. */ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("mStarted " + mStarted.get()); pw.println("mWifiWakeupEnabled: " + mWifiWakeupEnabled); @@ -273,12 +331,24 @@ public class WifiWakeupController { pw.println("mSavedSsidsOnDisable: " + mSavedSsidsOnDisable); } - /** - * Wrapper around Settings to make testing easier. - */ - public static class SettingsFacade { - public int getInt(ContentResolver resolver, String name, int def) { - return Settings.Global.getInt(resolver, name, def); + /** Class to track counts for saved networks for logging. */ + private static class SavedNetworkCounts { + int total; + int open; + int enabled; + int noInternetAccess; + int noInternetAccessExpected; + int useExternalScores; + int blacklisted; + + void clear() { + total = 0; + open = 0; + enabled = 0; + noInternetAccess = 0; + noInternetAccessExpected = 0; + useExternalScores = 0; + blacklisted = 0; } } } diff --git a/src/com/android/networkrecommendation/wakeup/WifiWakeupHelper.java b/src/com/android/networkrecommendation/wakeup/WifiWakeupHelper.java new file mode 100644 index 0000000..c62c24e --- /dev/null +++ b/src/com/android/networkrecommendation/wakeup/WifiWakeupHelper.java @@ -0,0 +1,240 @@ +/* + * 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.networkrecommendation.wakeup; + +import static com.android.networkrecommendation.Constants.TAG; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; +import android.text.TextUtils; +import android.util.ArraySet; +import com.android.networkrecommendation.R; +import com.android.networkrecommendation.config.G; +import com.android.networkrecommendation.util.Blog; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * Helper class for logging Wi-Fi Wakeup sessions and showing showing notifications for {@link + * WifiWakeupController}. + */ +public class WifiWakeupHelper { + /** Unique ID used for the Wi-Fi Enabled notification. */ + private static final int NOTIFICATION_ID = R.string.wifi_wakeup_enabled_notification_title; + + @VisibleForTesting static final String KEY_SHOWN_SSIDS = "key_shown_ssids"; + private static final String ACTION_WIFI_SETTINGS = + "com.android.networkrecommendation.wakeup.ACTION_WIFI_SETTINGS"; + private static final String ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION = + "com.android.networkrecommendation.wakeup.ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION"; + private static final IntentFilter INTENT_FILTER = new IntentFilter(); + private static final long NETWORK_CONNECTED_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(30); + + static { + INTENT_FILTER.addAction(ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION); + INTENT_FILTER.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + } + + private final Context mContext; + private final Resources mResources; + private final NotificationManager mNotificationManager; + private final Handler mHandler; + private final WifiManager mWifiManager; + private final SharedPreferences mSharedPreferences; + + /** Whether the wakeup notification is currently displayed. */ + private boolean mNotificationShown; + /** True when the device is still connected to the first connected ssid since wakeup. */ + private boolean mWifiSessionStarted; + /** The first connected ssid after wakeup enabled wifi. */ + private String mConnectedSsid; + + private final BroadcastReceiver mBroadcastReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + try { + if (ACTION_WIFI_SETTINGS.equals(intent.getAction())) { + // TODO(netrec): Change to @SystemApi Settings.CONFIGURE_WIFI_SETTINGS + context.startActivity( + new Intent("android.settings.CONFIGURE_WIFI_SETTINGS") + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } else if (ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION.equals( + intent.getAction())) { + cancelNotificationIfNeeded(); + } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals( + intent.getAction())) { + networkStateChanged(); + } + } catch (RuntimeException re) { + // TODO(b/35044022) Remove try/catch after a couple of releases when we are confident + // this is not going to throw. + Blog.e(TAG, re, "RuntimeException in broadcast receiver."); + } + } + }; + + public WifiWakeupHelper( + Context context, + Resources resources, + Handler handler, + NotificationManager notificationManager, + WifiManager wifiManager) { + this( + context, + resources, + handler, + notificationManager, + wifiManager, + context.getSharedPreferences("wifi_wakeup", Context.MODE_PRIVATE)); + // BUG(26641175): Code coverage does not like line wraps at 'this($' + } + + @VisibleForTesting + WifiWakeupHelper( + Context context, + Resources resources, + Handler handler, + NotificationManager notificationManager, + WifiManager wifiManager, + SharedPreferences sharedPreferences) { + mContext = context; + mResources = resources; + mNotificationManager = notificationManager; + mHandler = handler; + mWifiManager = wifiManager; + mSharedPreferences = sharedPreferences; + mWifiSessionStarted = false; + mNotificationShown = false; + mConnectedSsid = null; + } + + /** + * Start tracking a wifi wakeup session. Optionally show a notification that Wi-Fi has been + * enabled by Wi-Fi Wakeup if one has not been displayed for this {@link WifiConfiguration}. + * + * @param wifiConfiguration the {@link WifiConfiguration} that triggered Wi-Fi to wakeup + */ + public void startWifiSession(@NonNull WifiConfiguration wifiConfiguration) { + mContext.registerReceiver( + mBroadcastReceiver, INTENT_FILTER, null /* broadcastPermission*/, mHandler); + mWifiSessionStarted = true; + mHandler.postDelayed( + () -> { + if (mWifiSessionStarted && mConnectedSsid == null) { + endWifiSession(); + } + }, + NETWORK_CONNECTED_TIMEOUT_MILLIS); + + Set<String> ssidSet = mSharedPreferences.getStringSet(KEY_SHOWN_SSIDS, null); + if (ssidSet == null) { + ssidSet = new ArraySet<>(); + } else if (ssidSet.contains(wifiConfiguration.SSID)) { + Blog.d( + TAG, + "Already showed Wi-Fi Enabled notification for ssid: %s", + Blog.pii(wifiConfiguration.SSID, G.Netrec.enableSensitiveLogging.get())); + return; + } + ssidSet.add(wifiConfiguration.SSID); + mSharedPreferences.edit().putStringSet(KEY_SHOWN_SSIDS, ssidSet).apply(); + + String title = mResources.getString(R.string.wifi_wakeup_enabled_notification_title); + String summary = + mResources.getString( + R.string.wifi_wakeup_enabled_notification_context, wifiConfiguration.SSID); + PendingIntent savedNetworkSettingsPendingIntent = + PendingIntent.getBroadcast( + mContext, + 0, + new Intent(ACTION_WIFI_SETTINGS), + PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent deletePendingIntent = + PendingIntent.getBroadcast( + mContext, + 0, + new Intent(ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION), + PendingIntent.FLAG_UPDATE_CURRENT); + Bundle extras = new Bundle(); + extras.putString( + Notification.EXTRA_SUBSTITUTE_APP_NAME, + mResources.getString(R.string.android_system_label)); + Notification notification = + new Notification.Builder(mContext) + .setContentTitle(title) + .setSmallIcon(R.drawable.ic_signal_wifi_badged_4_bars) + .setColor(mContext.getColor(R.color.color_tint)) + .setStyle(new Notification.BigTextStyle().bigText(summary)) + .setAutoCancel(true) + .setDeleteIntent(deletePendingIntent) + .setPriority(Notification.PRIORITY_LOW) + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setCategory(Notification.CATEGORY_STATUS) + .setContentIntent(savedNetworkSettingsPendingIntent) + .addExtras(extras) + .build(); + mNotificationManager.notify(TAG, NOTIFICATION_ID, notification); + mNotificationShown = true; + } + + private void networkStateChanged() { + if (!mWifiManager.isWifiEnabled()) { + endWifiSession(); + return; + } + + WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); + String ssid = wifiInfo == null ? null : wifiInfo.getSSID(); + if (mConnectedSsid == null) { + if (!TextUtils.isEmpty(ssid)) { + mConnectedSsid = ssid; + } + } else if (!TextUtils.equals(ssid, mConnectedSsid)) { + endWifiSession(); + } + } + + private void endWifiSession() { + if (mWifiSessionStarted) { + mWifiSessionStarted = false; + cancelNotificationIfNeeded(); + mConnectedSsid = null; + mContext.unregisterReceiver(mBroadcastReceiver); + } + } + + private void cancelNotificationIfNeeded() { + if (mNotificationShown) { + mNotificationShown = false; + mNotificationManager.cancel(TAG, NOTIFICATION_ID); + } + } +} diff --git a/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelector.java b/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelector.java index 7e3e884..61ed2cb 100644 --- a/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelector.java +++ b/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelector.java @@ -13,23 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.android.networkrecommendation.wakeup; import android.content.res.Resources; +import android.net.RecommendationRequest; +import android.net.RecommendationResult; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; - +import android.support.annotation.Nullable; +import android.util.ArraySet; import com.android.networkrecommendation.R; +import com.android.networkrecommendation.SynchronousNetworkRecommendationProvider; +import com.android.networkrecommendation.util.RoboCompatUtil; import com.android.networkrecommendation.util.ScanResultUtil; import com.android.networkrecommendation.util.WifiConfigurationUtil; - +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; -/** - * This class determines which network the framework would connect to if Wi-Fi was enabled. - */ +/** This class determines which network the framework would connect to if Wi-Fi was enabled. */ public class WifiWakeupNetworkSelector { private final int mThresholdQualifiedRssi24; private final int mThresholdQualifiedRssi5; @@ -39,31 +42,32 @@ public class WifiWakeupNetworkSelector { private final int mSecurityAward; private final int mBand5GHzAward; private final int mThresholdSaturatedRssi24; + private final SynchronousNetworkRecommendationProvider mNetworkRecommendationProvider; - public WifiWakeupNetworkSelector(Resources resources) { - mThresholdQualifiedRssi24 = resources.getInteger( - R.integer.config_netrec_wifi_score_low_rssi_threshold_24GHz); - mThresholdQualifiedRssi5 = resources.getInteger( - R.integer.config_netrec_wifi_score_low_rssi_threshold_5GHz); - mRssiScoreSlope = resources.getInteger( - R.integer.config_netrec_RSSI_SCORE_SLOPE); - mRssiScoreOffset = resources.getInteger( - R.integer.config_netrec_RSSI_SCORE_OFFSET); - mPasspointSecurityAward = resources.getInteger( - R.integer.config_netrec_PASSPOINT_SECURITY_AWARD); - mSecurityAward = resources.getInteger( - R.integer.config_netrec_SECURITY_AWARD); - mBand5GHzAward = resources.getInteger( - R.integer.config_netrec_5GHz_preference_boost_factor); - mThresholdSaturatedRssi24 = resources.getInteger( - R.integer.config_netrec_wifi_score_good_rssi_threshold_24GHz); + public WifiWakeupNetworkSelector( + Resources resources, + SynchronousNetworkRecommendationProvider networkRecommendationProvider) { + mThresholdQualifiedRssi24 = + resources.getInteger(R.integer.config_netrec_wifi_score_low_rssi_threshold_24GHz); + mThresholdQualifiedRssi5 = + resources.getInteger(R.integer.config_netrec_wifi_score_low_rssi_threshold_5GHz); + mRssiScoreSlope = resources.getInteger(R.integer.config_netrec_RSSI_SCORE_SLOPE); + mRssiScoreOffset = resources.getInteger(R.integer.config_netrec_RSSI_SCORE_OFFSET); + mPasspointSecurityAward = + resources.getInteger(R.integer.config_netrec_PASSPOINT_SECURITY_AWARD); + mSecurityAward = resources.getInteger(R.integer.config_netrec_SECURITY_AWARD); + mBand5GHzAward = resources.getInteger(R.integer.config_netrec_5GHz_preference_boost_factor); + mThresholdSaturatedRssi24 = + resources.getInteger(R.integer.config_netrec_wifi_score_good_rssi_threshold_24GHz); + mNetworkRecommendationProvider = networkRecommendationProvider; } - /** - * Returns the network that the framework would most likely connect to if Wi-Fi was enabled. - */ - public WifiConfiguration selectNetwork(Map<String, WifiConfiguration> savedNetworks, - List<ScanResult> scanResults) { + /** Returns the network that the framework would most likely connect to if Wi-Fi was enabled. */ + @Nullable + public WifiConfiguration selectNetwork( + Map<String, WifiConfiguration> savedNetworks, List<ScanResult> scanResults) { + Set<WifiConfiguration> openOrExternalConfigs = new ArraySet<>(); + List<ScanResult> openOrExternalScanResults = new ArrayList<>(); WifiConfiguration candidateWifiConfiguration = null; ScanResult candidateScanResult = null; int candidateScore = -1; @@ -73,14 +77,21 @@ public class WifiWakeupNetworkSelector { if (wifiConfiguration == null) { continue; } - if (ScanResultUtil.is5GHz(scanResult) && scanResult.level < mThresholdQualifiedRssi5 - || ScanResultUtil.is24GHz(scanResult) - && scanResult.level < mThresholdQualifiedRssi24) { + if ((ScanResultUtil.is5GHz(scanResult) && scanResult.level < mThresholdQualifiedRssi5) + || (ScanResultUtil.is24GHz(scanResult) + && scanResult.level < mThresholdQualifiedRssi24)) { continue; } if (!ScanResultUtil.doesScanResultMatchWithNetwork(scanResult, wifiConfiguration)) { continue; } + if (WifiConfigurationUtil.isConfigForOpenNetwork(wifiConfiguration) + || RoboCompatUtil.getInstance().useExternalScores(wifiConfiguration)) { + // All open and externally scored networks should defer to network recommendations. + openOrExternalConfigs.add(wifiConfiguration); + openOrExternalScanResults.add(scanResult); + continue; + } int score = calculateScore(scanResult, wifiConfiguration); if (candidateScanResult == null || calculateScore(scanResult, wifiConfiguration) > candidateScore) { @@ -89,14 +100,26 @@ public class WifiWakeupNetworkSelector { candidateScore = score; } } + if (candidateWifiConfiguration == null && !openOrExternalConfigs.isEmpty()) { + // TODO(netrec): Add connectableConfigs after next SystemApi drop + RecommendationRequest request = + new RecommendationRequest.Builder() + .setScanResults(openOrExternalScanResults.toArray(new ScanResult[0])) + .build(); + RecommendationResult result = + mNetworkRecommendationProvider.requestRecommendation(request); + return result.getWifiConfiguration(); + } return candidateWifiConfiguration; } private int calculateScore(ScanResult scanResult, WifiConfiguration wifiConfiguration) { int score = 0; // Calculate the RSSI score. - int rssi = scanResult.level <= mThresholdSaturatedRssi24 - ? scanResult.level : mThresholdSaturatedRssi24; + int rssi = + scanResult.level <= mThresholdSaturatedRssi24 + ? scanResult.level + : mThresholdSaturatedRssi24; score += (rssi + mRssiScoreOffset) * mRssiScoreSlope; // 5GHz band bonus. @@ -105,7 +128,7 @@ public class WifiWakeupNetworkSelector { } // Security award. - if (wifiConfiguration.isPasspoint()) { + if (RoboCompatUtil.getInstance().isPasspoint(wifiConfiguration)) { score += mPasspointSecurityAward; } else if (!WifiConfigurationUtil.isConfigForOpenNetwork(wifiConfiguration)) { score += mSecurityAward; diff --git a/src/com/android/networkrecommendation/wakeup/WifiWakeupNotificationHelper.java b/src/com/android/networkrecommendation/wakeup/WifiWakeupNotificationHelper.java deleted file mode 100644 index 968a71c..0000000 --- a/src/com/android/networkrecommendation/wakeup/WifiWakeupNotificationHelper.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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.networkrecommendation.wakeup; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.os.Bundle; -import android.os.Handler; -import android.provider.Settings; -import android.support.annotation.NonNull; -import android.support.annotation.VisibleForTesting; -import android.text.TextUtils; -import android.util.ArraySet; - -import com.android.networkrecommendation.R; -import com.android.networkrecommendation.util.Blog; - -import java.util.Set; -import java.util.concurrent.TimeUnit; - -/** - * Helper class for building and showing notifications for {@link WifiWakeupController}. - */ -public class WifiWakeupNotificationHelper { - private static final String TAG = "WifiWakeupNotifHelper"; - - /** Unique ID used for the Wi-Fi Enabled notification. */ - private static final int NOTIFICATION_ID = R.string.wifi_wakeup_enabled_notification_title; - @VisibleForTesting - static final String KEY_SHOWN_SSIDS = "key_shown_ssids"; - private static final String ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION = - "com.android.networkrecommendation.ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION"; - private static final IntentFilter INTENT_FILTER = new IntentFilter(); - private static final long NETWORK_CONNECTED_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(30); - - static { - INTENT_FILTER.addAction(ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION); - INTENT_FILTER.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - } - - private final Context mContext; - private final Resources mResources; - private final NotificationManager mNotificationManager; - private final Handler mHandler; - private final WifiManager mWifiManager; - private final SharedPreferences mSharedPreferences; - - @VisibleForTesting - final Runnable mCancelNotification = new Runnable() { - @Override - public void run() { - cancelNotificationAndUnregisterReceiver(); - } - }; - - @VisibleForTesting - final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION.equals(intent.getAction())) { - cancelNotificationAndUnregisterReceiver(); - } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) { - networkStateChanged(); - } - } - }; - private boolean mNotificationShown; - private String mConnectedSsid; - - public WifiWakeupNotificationHelper(Context context, Resources resources, Handler handler, - NotificationManager notificationManager, WifiManager wifiManager) { - this(context, resources, handler, notificationManager, wifiManager, - context.getSharedPreferences("wifi_wakeup", Context.MODE_PRIVATE)); - } - - @VisibleForTesting - WifiWakeupNotificationHelper(Context context, Resources resources, Handler handler, - NotificationManager notificationManager, WifiManager wifiManager, - SharedPreferences sharedPreferences) { - mContext = context; - mResources = resources; - mNotificationManager = notificationManager; - mHandler = handler; - mWifiManager = wifiManager; - mSharedPreferences = sharedPreferences; - mNotificationShown = false; - mConnectedSsid = null; - } - - /** - * Show a notification that Wi-Fi has been enabled by Wi-Fi Wakeup. - * - * @param wifiConfiguration the {@link WifiConfiguration} that triggered Wi-Fi to wakeup - */ - public void maybeShowWifiEnabledNotification(@NonNull WifiConfiguration wifiConfiguration) { - Set<String> ssidSet = mSharedPreferences.getStringSet(KEY_SHOWN_SSIDS, null); - if (ssidSet == null) { - ssidSet = new ArraySet<>(); - } else if (ssidSet.contains(wifiConfiguration.SSID)) { - Blog.d(TAG, "Already showed Wi-Fi Enabled notification for ssid: " - + wifiConfiguration.SSID); - return; - } - ssidSet.add(wifiConfiguration.SSID); - mSharedPreferences.edit().putStringSet(KEY_SHOWN_SSIDS, ssidSet).apply(); - - String title = mResources.getString( - R.string.wifi_wakeup_enabled_notification_title); - String summary = mResources.getString( - R.string.wifi_wakeup_enabled_notification_context, wifiConfiguration.SSID); - PendingIntent savedNetworkSettingsPendingIntent = PendingIntent.getActivity(mContext, 0, - new Intent(Settings.ACTION_CONFIGURE_WIFI_SETTINGS), - PendingIntent.FLAG_UPDATE_CURRENT); - PendingIntent deletePendingIntent = PendingIntent.getActivity(mContext, 0, - new Intent(ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION), - PendingIntent.FLAG_UPDATE_CURRENT); - Bundle extras = new Bundle(); - extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, - mResources.getString(R.string.android_system_label)); - Notification notification = new Notification.Builder(mContext) - .setContentTitle(title) - .setSmallIcon(R.drawable.ic_wifi_signal_4) - .setStyle(new Notification.BigTextStyle().bigText(summary)) - .setAutoCancel(true) - .setDeleteIntent(deletePendingIntent) - .setPriority(Notification.PRIORITY_LOW) - .setVisibility(Notification.VISIBILITY_PUBLIC) - .setCategory(Notification.CATEGORY_STATUS) - .setContentIntent(savedNetworkSettingsPendingIntent) - .addExtras(extras) - .build(); - mNotificationManager.notify(TAG, NOTIFICATION_ID, notification); - mNotificationShown = true; - mContext.registerReceiver(mBroadcastReceiver, INTENT_FILTER, null /* broadcastPermission*/, - mHandler); - mHandler.postDelayed(mCancelNotification, NETWORK_CONNECTED_TIMEOUT_MILLIS); - } - - private void cancelNotificationAndUnregisterReceiver() { - if (mNotificationShown) { - mNotificationShown = false; - mConnectedSsid = null; - mNotificationManager.cancel(TAG, NOTIFICATION_ID); - mContext.unregisterReceiver(mBroadcastReceiver); - } - } - - private void networkStateChanged() { - if (!mWifiManager.isWifiEnabled()) { - cancelNotificationAndUnregisterReceiver(); - return; - } - - WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); - String ssid = wifiInfo == null ? null : wifiInfo.getSSID(); - if (mConnectedSsid == null) { - mConnectedSsid = ssid; - mHandler.removeCallbacks(mCancelNotification); - } else { - if (!TextUtils.equals(ssid, mConnectedSsid)) { - cancelNotificationAndUnregisterReceiver(); - } - } - } -} diff --git a/tests/src/com/android/networkrecommendation/wakeup/WifiWakeupControllerTest.java b/tests/src/com/android/networkrecommendation/wakeup/WifiWakeupControllerTest.java deleted file mode 100644 index 72a4571..0000000 --- a/tests/src/com/android/networkrecommendation/wakeup/WifiWakeupControllerTest.java +++ /dev/null @@ -1,429 +0,0 @@ -/* - * 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.networkrecommendation.wakeup; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyList; -import static org.mockito.Matchers.anyMap; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.IntentFilter; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiSsid; -import android.os.Handler; -import android.os.Looper; -import android.provider.Settings; -import android.support.test.runner.AndroidJUnit4; - -import com.android.networkrecommendation.TestUtil; - -import com.google.android.collect.Lists; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.io.StringWriter; - -/** - * Unit tests for {@link WifiWakeupController}. - */ -@RunWith(AndroidJUnit4.class) -public class WifiWakeupControllerTest { - private static final ScanResult OPEN_SCAN_RESULT = buildScanResult("ssid"); - private static final ScanResult SAVED_SCAN_RESULT = buildScanResult("ssid1"); - private static final ScanResult SAVED_SCAN_RESULT2 = buildScanResult("ssid2"); - private static final ScanResult SAVED_SCAN_RESULT_EXTERNAL = buildScanResult("ssid3"); - - private static final WifiConfiguration SAVED_WIFI_CONFIGURATION = new WifiConfiguration(); - private static final WifiConfiguration SAVED_WIFI_CONFIGURATION2 = new WifiConfiguration(); - private static final WifiConfiguration SAVED_WIFI_CONFIGURATION_EXTERNAL = - new WifiConfiguration(); - - static { - SAVED_WIFI_CONFIGURATION.SSID = "\"" + SAVED_SCAN_RESULT.SSID + "\""; - SAVED_WIFI_CONFIGURATION.status = WifiConfiguration.Status.CURRENT; - SAVED_WIFI_CONFIGURATION.validatedInternetAccess = true; - SAVED_WIFI_CONFIGURATION2.SSID = "\"" + SAVED_SCAN_RESULT.SSID + "\""; - SAVED_WIFI_CONFIGURATION2.status = WifiConfiguration.Status.ENABLED; - SAVED_WIFI_CONFIGURATION2.validatedInternetAccess = true; - SAVED_WIFI_CONFIGURATION_EXTERNAL.SSID = "\"" + SAVED_SCAN_RESULT_EXTERNAL.SSID + "\""; - SAVED_WIFI_CONFIGURATION_EXTERNAL.useExternalScores = true; - SAVED_WIFI_CONFIGURATION_EXTERNAL.status = WifiConfiguration.Status.ENABLED; - SAVED_WIFI_CONFIGURATION_EXTERNAL.validatedInternetAccess = true; - } - - private static ScanResult buildScanResult(String ssid) { - ScanResult scanResult = new ScanResult(WifiSsid.createFromAsciiEncoded(ssid), - "00:00:00:00:00:00", 0L, -1, null, "", 0, 0, 0); - scanResult.informationElements = new ScanResult.InformationElement[0]; - return scanResult; - } - - @Mock private Context mContext; - @Mock private ContentResolver mContentResolver; - @Mock private WifiWakeupNetworkSelector mWifiWakeupNetworkSelector; - @Mock private WifiWakeupNotificationHelper mWifiWakeupNotificationHelper; - @Mock private WifiManager mWifiManager; - @Mock private WifiWakeupController.SettingsFacade mSettingsFacade; - @Captor private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor; - - private WifiWakeupController mWifiWakeupController; - private BroadcastReceiver mBroadcastReceiver; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - when(mWifiManager.getWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_DISABLED); - when(mSettingsFacade.getInt(eq(mContentResolver), - eq(Settings.Global.WIFI_WAKEUP_ENABLED), anyInt())).thenReturn(1); - when(mSettingsFacade.getInt(eq(mContentResolver), - eq(Settings.Global.AIRPLANE_MODE_ON), anyInt())).thenReturn(0); - - mWifiWakeupController = new WifiWakeupController(mContext, mContentResolver, - Looper.getMainLooper(), mWifiManager, mWifiWakeupNetworkSelector, - mWifiWakeupNotificationHelper, mSettingsFacade); - mWifiWakeupController.start(); - - verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), - any(IntentFilter.class), anyString(), any(Handler.class)); - mBroadcastReceiver = mBroadcastReceiverCaptor.getValue(); - } - - /** - * When the NetworkRecommendationService associated with this WifiWakeupController is unbound, - * this WifiWakeupController should no longer function. - */ - @Test - public void wifiWakeupControllerStopped() { - mWifiWakeupController.stop(); - - verify(mContext).unregisterReceiver(mBroadcastReceiver); - } - - /** - * When Wi-Fi is disabled and a saved network is in the scan list, and then this network is not - * in the scan list 3x, and then it is, Wi-Fi should be enabled. - */ - @Test - public void wifiEnabled_userDisabledWifiNearSavedNetwork_thenLeaves_thenMovesBack() { - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION)); - when(mWifiManager.getScanResults()).thenReturn( - Lists.newArrayList(SAVED_SCAN_RESULT), - Lists.newArrayList(OPEN_SCAN_RESULT), - Lists.newArrayList(OPEN_SCAN_RESULT), - Lists.newArrayList(OPEN_SCAN_RESULT), - Lists.newArrayList(SAVED_SCAN_RESULT)); - when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())) - .thenReturn(null, SAVED_WIFI_CONFIGURATION); - when(mWifiManager.getWifiState()) - .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED); - - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verify(mWifiManager, never()).setWifiEnabled(true); - - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verify(mWifiManager).setWifiEnabled(true); - verify(mWifiWakeupNotificationHelper) - .maybeShowWifiEnabledNotification(SAVED_WIFI_CONFIGURATION); - } - - /** - * When Wi-Fi is disabled and a saved network is in the scan list, and then another scan result - * comes in 3x with only a different saved network, Wi-Fi should be enabled. - */ - @Test - public void wifiEnabled_userDisabledWifiNearSavedNetwork_thenMovesToAnotherSavedNetwork() { - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION2)); - when(mWifiManager.getScanResults()).thenReturn( - Lists.newArrayList(SAVED_SCAN_RESULT), - Lists.newArrayList(SAVED_SCAN_RESULT2)); - when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())) - .thenReturn(SAVED_WIFI_CONFIGURATION2); - when(mWifiManager.getWifiState()) - .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED); - - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - - verify(mWifiManager, never()).setWifiEnabled(true); - - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verify(mWifiManager).setWifiEnabled(true); - verify(mWifiWakeupNotificationHelper) - .maybeShowWifiEnabledNotification(SAVED_WIFI_CONFIGURATION2); - } - - /** - * When a user disables Wi-Fi when there is a saved network marked with - * {@link WifiConfiguration#useExternalScores} in the scan list, Wi-Fi should not be enabled if - * the {@link WifiWakeupNetworkSelector} does not return an ssid. - * - * When {@link WifiWakeupNetworkSelector} does return an ssid, Wi-Fi should - * be enabled (in absence of a scan list without the saved network) because networks marked - * with external scores are not tracked by {@link WifiWakeupController}. - */ - @Test - public void wifiEnabled_userDisablesWifiNearExternallyScoredNetwork_thenNetworkIsSelected() { - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL)); - when(mWifiManager.getScanResults()) - .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT_EXTERNAL)); - when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())) - .thenReturn(null, SAVED_WIFI_CONFIGURATION_EXTERNAL); - when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); - - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verify(mWifiManager, never()).setWifiEnabled(true); - - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verify(mWifiManager).setWifiEnabled(true); - verify(mWifiWakeupNotificationHelper) - .maybeShowWifiEnabledNotification(SAVED_WIFI_CONFIGURATION_EXTERNAL); - } - - /** - * When Wi-Fi is enabled and a saved network is in the scan list, Wi-Fi should not be enabled. - */ - @Test - public void wifiNotEnabled_wifiAlreadyEnabled() { - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL)); - when(mWifiManager.getScanResults()) - .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); - when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED); - - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verifyZeroInteractions(mWifiWakeupNetworkSelector); - verify(mWifiManager, never()).setWifiEnabled(true); - } - - /** - * When Wi-Fi is disabled and a saved network is in the scan list, but - * {@link WifiWakeupNetworkSelector}, does not choose this network, Wi-Fi should not be enabled. - */ - @Test - public void wifiNotEnabled_userNearSavedNetworkButNotSelected() { - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL)); - when(mWifiManager.getScanResults()) - .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); - when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())).thenReturn(null); - when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); - - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verify(mWifiManager, never()).setWifiEnabled(true); - } - - /** - * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled - * if the user has not enabled the wifi wakeup feature. - */ - @Test - public void wifiNotEnabled_userDisablesWifiWakeupFeature() { - when(mSettingsFacade.getInt(eq(mContentResolver), - eq(Settings.Global.WIFI_WAKEUP_ENABLED), anyInt())).thenReturn(0); - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL)); - when(mWifiManager.getScanResults()) - .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); - when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); - - mWifiWakeupController.mContentObserver.onChange(true); - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verifyZeroInteractions(mWifiWakeupNetworkSelector); - verify(mWifiManager, never()).setWifiEnabled(true); - } - - /** - * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled if - * the user is in airplane mode. - */ - @Test - public void wifiNotEnabled_userIsInAirplaneMode() { - when(mSettingsFacade.getInt(eq(mContentResolver), - eq(Settings.Global.AIRPLANE_MODE_ON), anyInt())).thenReturn(1); - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL)); - when(mWifiManager.getScanResults()) - .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); - when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); - - mWifiWakeupController.mContentObserver.onChange(true); - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verifyZeroInteractions(mWifiWakeupNetworkSelector); - verify(mWifiManager, never()).setWifiEnabled(true); - } - - /** - * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled if - * the wifi AP state is not disabled. - */ - @Test - public void wifiNotEnabled_wifiApStateIsNotDisabled() { - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL)); - when(mWifiManager.getScanResults()) - .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); - when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED); - when(mWifiManager.getWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_ENABLED); - - mWifiWakeupController.mContentObserver.onChange(true); - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendWifiApStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verifyZeroInteractions(mWifiWakeupNetworkSelector); - verify(mWifiManager, never()).setWifiEnabled(true); - } - - /** - * If Wi-Fi is disabled when a saved network is the scan list, Wi-Fi should not be enabled no - * matter how many scans are performed that include the saved network. - */ - @Test - public void wifiNotEnabled_userDisablesWifiNearSavedNetwork_thenDoesNotLeave() { - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL)); - when(mWifiManager.getScanResults()) - .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); - - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verifyZeroInteractions(mWifiWakeupNetworkSelector); - verify(mWifiManager, never()).setWifiEnabled(true); - } - - /** - * If Wi-Fi is disabled when a saved network is in the scan list, and then that saved network - * is removed, Wi-Fi is not enabled even if the user leaves range of that network and returns. - */ - @Test - public void wifiNotEnabled_userDisablesWifiNearSavedNetwork_thenRemovesNetwork_thenStays() { - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION), - Lists.<WifiConfiguration>newArrayList()); - when(mWifiManager.getScanResults()) - .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)) - .thenReturn(Lists.<ScanResult>newArrayList()) - .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT)); - when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())).thenReturn(null); - when(mWifiManager.getWifiState()) - .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED); - - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verify(mWifiManager, never()).setWifiEnabled(true); - } - - /** - * If Wi-Fi is disabled when 2 saved networks are in the scan list, and then a scan result - * comes in with only 1 saved network 3x, Wi-Fi should not be enabled. - */ - @Test - public void wifiNotEnabled_userDisablesWifiNear2SavedNetworks_thenLeavesRangeOfOneOfThem() { - when(mWifiManager.getConfiguredNetworks()).thenReturn( - Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION2)); - when(mWifiManager.getScanResults()).thenReturn( - Lists.newArrayList(SAVED_SCAN_RESULT, - SAVED_SCAN_RESULT2), - Lists.newArrayList(SAVED_SCAN_RESULT)); - when(mWifiManager.getWifiState()) - .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED); - - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext); - - verifyZeroInteractions(mWifiWakeupNetworkSelector); - verify(mWifiManager, never()).setWifiEnabled(true); - } - - /** Test dump() does not crash. */ - @Test - public void testDump() { - StringWriter stringWriter = new StringWriter(); - mWifiWakeupController.dump( - new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); - } -} diff --git a/tests/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelectorTest.java b/tests/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelectorTest.java deleted file mode 100644 index bdb1a52..0000000 --- a/tests/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelectorTest.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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.networkrecommendation.wakeup; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.when; - -import android.content.res.Resources; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiSsid; -import android.support.test.runner.AndroidJUnit4; -import android.util.ArrayMap; - -import com.android.networkrecommendation.R; - -import com.google.android.collect.Lists; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.List; - -/** - * Unit tests for {@link WifiWakeupNetworkSelector} - */ -@RunWith(AndroidJUnit4.class) -public class WifiWakeupNetworkSelectorTest { - private static final String SSID = "ssid"; - private static final String SSID2 = "ssid2"; - - private static final WifiConfiguration WIFI_CONFIGURATION_PSK = new WifiConfiguration(); - private static final WifiConfiguration WIFI_CONFIGURATION_NONE = new WifiConfiguration(); - private static final ArrayMap<String, WifiConfiguration> SAVED_WIFI_CONFIGURATION_MAP = - new ArrayMap<>(); - - static { - WIFI_CONFIGURATION_PSK.SSID = "\"" + SSID + "\""; - WIFI_CONFIGURATION_PSK.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); - SAVED_WIFI_CONFIGURATION_MAP.put(SSID, WIFI_CONFIGURATION_PSK); - - WIFI_CONFIGURATION_NONE.SSID = "\"" + SSID2 + "\""; - WIFI_CONFIGURATION_NONE.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - SAVED_WIFI_CONFIGURATION_MAP.put(SSID2, WIFI_CONFIGURATION_NONE); - } - - private static ScanResult buildScanResult(String ssid, int level, int frequency, String caps) { - return new ScanResult(WifiSsid.createFromAsciiEncoded(ssid), - "00:00:00:00:00:00", 0L, -1, null, caps, level, frequency, 0); - } - - private static final int MIN_QUALIFIED_24 = -73; - private static final int MIN_QUALIFIED_5 = -70; - private static final int FREQUENCY_24 = 2450; - private static final int FREQUENCY_5 = 5000; - private static final String CAPABILITIES_NONE = ""; - private static final String CAPABILITIES_PSK = "PSK"; - - @Mock private Resources mResources; - - private WifiWakeupNetworkSelector mWifiWakeupNetworkSelector; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - when(mResources.getInteger( - R.integer.config_netrec_wifi_score_low_rssi_threshold_24GHz)) - .thenReturn(MIN_QUALIFIED_24); - when(mResources.getInteger( - R.integer.config_netrec_wifi_score_low_rssi_threshold_5GHz)) - .thenReturn(MIN_QUALIFIED_5); - when(mResources.getInteger( - R.integer.config_netrec_5GHz_preference_boost_factor)) - .thenReturn(100); - - mWifiWakeupNetworkSelector = new WifiWakeupNetworkSelector(mResources); - } - - @Test - public void testSelectNetwork_noSavedNetworksInScanResults() { - List<ScanResult> scanResults = Lists.newArrayList( - buildScanResult("blah", MIN_QUALIFIED_5 + 1, FREQUENCY_5, CAPABILITIES_NONE), - buildScanResult("blahtoo", MIN_QUALIFIED_24 + 1, FREQUENCY_24, CAPABILITIES_NONE)); - - WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector - .selectNetwork(SAVED_WIFI_CONFIGURATION_MAP, scanResults); - - assertNull(selectedNetwork); - } - - @Test - public void testSelectNetwork_noQualifiedSavedNetworks() { - List<ScanResult> scanResults = Lists.newArrayList( - buildScanResult(SSID2, MIN_QUALIFIED_5 - 1, FREQUENCY_5, CAPABILITIES_NONE), - buildScanResult(SSID2, MIN_QUALIFIED_24 - 1, FREQUENCY_24, CAPABILITIES_NONE)); - - WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector - .selectNetwork(SAVED_WIFI_CONFIGURATION_MAP, scanResults); - - assertNull(selectedNetwork); - } - - @Test - public void testSelectNetwork_noMatchingScanResults() { - List<ScanResult> scanResults = Lists.newArrayList( - buildScanResult(SSID, MIN_QUALIFIED_5 + 1, FREQUENCY_5, CAPABILITIES_NONE), - buildScanResult(SSID, MIN_QUALIFIED_24 + 1, FREQUENCY_24, CAPABILITIES_NONE)); - - WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector - .selectNetwork(SAVED_WIFI_CONFIGURATION_MAP, scanResults); - - assertNull(selectedNetwork); - } - - @Test - public void testSelectNetwork_secureNetworkOverUnsecure() { - List<ScanResult> scanResults = Lists.newArrayList( - buildScanResult(SSID, MIN_QUALIFIED_5 + 1, FREQUENCY_5, CAPABILITIES_PSK), - buildScanResult(SSID2, MIN_QUALIFIED_5 + 1, FREQUENCY_5, CAPABILITIES_NONE)); - - WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector - .selectNetwork(SAVED_WIFI_CONFIGURATION_MAP, scanResults); - - assertEquals(WIFI_CONFIGURATION_PSK, selectedNetwork); - } -} diff --git a/tests/src/com/android/networkrecommendation/wakeup/WifiWakeupNotificationHelperTest.java b/tests/src/com/android/networkrecommendation/wakeup/WifiWakeupNotificationHelperTest.java deleted file mode 100644 index f2c68d0..0000000 --- a/tests/src/com/android/networkrecommendation/wakeup/WifiWakeupNotificationHelperTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2016 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.networkrecommendation.wakeup; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Notification; -import android.app.NotificationManager; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiSsid; -import android.os.Handler; -import android.os.Looper; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.Set; - -/** - * Unit tests for {@link WifiWakeupNetworkSelector} - */ -@RunWith(AndroidJUnit4.class) -public class WifiWakeupNotificationHelperTest { - private static final String SSID = "ssid"; - private static final WifiConfiguration WIFI_CONFIGURATION = new WifiConfiguration(); - - static { - WIFI_CONFIGURATION.SSID = "\"" + SSID + "\""; - } - - private Context mContext; - @Mock private NotificationManager mNotificationManager; - @Mock private WifiManager mWifiManager; - private SharedPreferences mSharedPreferences; - private String mSharedPreferenceName; - - private WifiWakeupNotificationHelper mWifiWakeupNotificationHelper; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mContext = InstrumentationRegistry.getTargetContext(); - mSharedPreferenceName = "WifiWakeupNotificationHelperTest"; - mSharedPreferences = mContext.getSharedPreferences(mSharedPreferenceName, - Context.MODE_PRIVATE); - - mWifiWakeupNotificationHelper = new WifiWakeupNotificationHelper(mContext, - mContext.getResources(), new Handler(Looper.getMainLooper()), mNotificationManager, - mWifiManager, mSharedPreferences); - } - - @After - public void tearDown() throws Exception { - mContext.deleteSharedPreferences(mSharedPreferenceName); - } - - @Test - public void notificationShowsOncePerSsid() { - mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION); - mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION); - - verify(mNotificationManager, times(1)) - .notify(anyString(), anyInt(), any(Notification.class)); - Set<String> ssidSet = mSharedPreferences.getStringSet( - WifiWakeupNotificationHelper.KEY_SHOWN_SSIDS, null); - assertEquals(1, ssidSet.size()); - assertTrue(ssidSet.contains(WIFI_CONFIGURATION.SSID)); - } - - @Test - public void notificationCanceledWhenNeverConnected() { - mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION); - - mWifiWakeupNotificationHelper.mCancelNotification.run(); - - verify(mNotificationManager).cancel(anyString(), anyInt()); - } - - @Test - public void notificationCanceledWhenWifiDisabled() { - mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION); - - when(mWifiManager.isWifiEnabled()).thenReturn(false); - - mWifiWakeupNotificationHelper.mBroadcastReceiver.onReceive(mContext, - new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); - - verify(mNotificationManager).cancel(anyString(), anyInt()); - } - - @Test - public void notificationCanceledWhenSsidChanged() { - WifiInfo firstWifiInfo = new WifiInfo(); - firstWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(SSID)); - WifiInfo secondWifiInfo = new WifiInfo(); - firstWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded("blah")); - - mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION); - - when(mWifiManager.isWifiEnabled()).thenReturn(true); - when(mWifiManager.getConnectionInfo()).thenReturn(firstWifiInfo, secondWifiInfo); - - mWifiWakeupNotificationHelper.mBroadcastReceiver.onReceive(mContext, - new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); - - verify(mNotificationManager, never()).cancel(anyString(), anyInt()); - - mWifiWakeupNotificationHelper.mBroadcastReceiver.onReceive(mContext, - new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)); - - verify(mNotificationManager).cancel(anyString(), anyInt()); - } -} |