summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java327
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java6
-rw-r--r--libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java6
-rw-r--r--libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/SavedNetworkTrackerTest.java306
-rw-r--r--libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/TestUtils.java7
-rw-r--r--libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java34
6 files changed, 666 insertions, 20 deletions
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java
new file mode 100644
index 000000000..9a12ea3ba
--- /dev/null
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2019 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.wifitrackerlib;
+
+import static androidx.core.util.Preconditions.checkNotNull;
+
+import static com.android.wifitrackerlib.StandardWifiEntry.wifiConfigToStandardWifiEntryKey;
+
+import static java.util.stream.Collectors.groupingBy;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkScoreManager;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.AnyThread;
+import androidx.annotation.GuardedBy;
+import androidx.annotation.MainThread;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
+import androidx.lifecycle.Lifecycle;
+
+import java.time.Clock;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Wi-Fi tracker that provides all Wi-Fi related data to the Saved Networks page.
+ *
+ * These include
+ * - List of WifiEntries for all saved networks, dynamically updated with ScanResults
+ * - List of WifiEntries for all saved subscriptions, dynamically updated with ScanResults
+ */
+public class SavedNetworkTracker extends BaseWifiTracker {
+
+ private static final String TAG = "SavedNetworkTracker";
+
+ private final SavedNetworkTrackerCallback mListener;
+
+ // Lock object for data returned by the public API
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock") private final List<WifiEntry> mSavedWifiEntries = new ArrayList<>();
+ @GuardedBy("mLock") private final List<WifiEntry> mSubscriptionWifiEntries = new ArrayList<>();
+
+ // Cache containing visible StandardWifiEntries. Must be accessed only by the worker thread.
+ private final Map<String, StandardWifiEntry> mStandardWifiEntryCache = new HashMap<>();
+
+ public SavedNetworkTracker(@NonNull Lifecycle lifecycle, @NonNull Context context,
+ @NonNull WifiManager wifiManager,
+ @NonNull ConnectivityManager connectivityManager,
+ @NonNull NetworkScoreManager networkScoreManager,
+ @NonNull Handler mainHandler,
+ @NonNull Handler workerHandler,
+ @NonNull Clock clock,
+ long maxScanAgeMillis,
+ long scanIntervalMillis,
+ @Nullable SavedNetworkTracker.SavedNetworkTrackerCallback listener) {
+ super(lifecycle, context, wifiManager, connectivityManager, networkScoreManager,
+ mainHandler, workerHandler, clock, maxScanAgeMillis, scanIntervalMillis, listener,
+ TAG);
+ mListener = listener;
+ }
+
+ /**
+ * Returns a list of WifiEntries for all saved networks. If a network is in range, the
+ * corresponding WifiEntry will be updated with live ScanResult data.
+ * @return
+ */
+ @AnyThread
+ @NonNull
+ public List<WifiEntry> getSavedWifiEntries() {
+ synchronized (mLock) {
+ return new ArrayList<>(mSavedWifiEntries);
+ }
+ }
+
+ /**
+ * Returns a list of WifiEntries for all saved subscriptions. If a subscription network is in
+ * range, the corresponding WifiEntry will be updated with live ScanResult data.
+ * @return
+ */
+ @AnyThread
+ @NonNull
+ public List<WifiEntry> getSubscriptionWifiEntries() {
+ synchronized (mLock) {
+ return new ArrayList<>(mSubscriptionWifiEntries);
+ }
+ }
+
+ @WorkerThread
+ @Override
+ protected void handleOnStart() {
+ updateStandardWifiEntryConfigs(mWifiManager.getConfiguredNetworks());
+ conditionallyUpdateScanResults(true /* lastScanSucceeded */);
+ updateSavedWifiEntries();
+ updateSubscriptionWifiEntries();
+ }
+
+ @WorkerThread
+ @Override
+ protected void handleWifiStateChangedAction() {
+ conditionallyUpdateScanResults(true /* lastScanSucceeded */);
+ updateSavedWifiEntries();
+ updateSubscriptionWifiEntries();
+ }
+
+ @WorkerThread
+ @Override
+ protected void handleScanResultsAvailableAction(@Nullable Intent intent) {
+ //TODO(b/70983952): Add PasspointWifiEntry and update their scans here.
+ checkNotNull(intent, "Intent cannot be null!");
+ conditionallyUpdateScanResults(intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED,
+ true /* defaultValue */));
+ updateSavedWifiEntries();
+ updateSubscriptionWifiEntries();
+ }
+
+ @WorkerThread
+ @Override
+ protected void handleConfiguredNetworksChangedAction(@Nullable Intent intent) {
+ checkNotNull(intent, "Intent cannot be null!");
+
+ final WifiConfiguration config =
+ (WifiConfiguration) intent.getExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
+ if (config != null) {
+ updateStandardWifiEntryConfig(
+ config, (Integer) intent.getExtra(WifiManager.EXTRA_CHANGE_REASON));
+ } else {
+ updateStandardWifiEntryConfigs(mWifiManager.getConfiguredNetworks());
+ }
+ updateSavedWifiEntries();
+ }
+
+ private void updateSavedWifiEntries() {
+ synchronized (mLock) {
+ mSavedWifiEntries.clear();
+ mSavedWifiEntries.addAll(mStandardWifiEntryCache.values());
+ Collections.sort(mSavedWifiEntries);
+ if (isVerboseLoggingEnabled()) {
+ Log.v(TAG, "Updated SavedWifiEntries: "
+ + Arrays.toString(mSavedWifiEntries.toArray()));
+ }
+ }
+ notifyOnSavedWifiEntriesChanged();
+ }
+
+ private void updateSubscriptionWifiEntries() {
+ synchronized (mLock) {
+ mSubscriptionWifiEntries.clear();
+ // TODO(b/70983952): Implement PasspointWifiEntry and add here
+ // mSubscriptionWifiEntries.addAll(mPasspointWifiEntryCache.values());
+ Collections.sort(mSubscriptionWifiEntries);
+ if (isVerboseLoggingEnabled()) {
+ Log.v(TAG, "Updated SubscriptionWifiEntries: "
+ + Arrays.toString(mSubscriptionWifiEntries.toArray()));
+ }
+ }
+ notifyOnSubscriptionWifiEntriesChanged();
+ }
+
+ private void updateStandardWifiEntryScans(@NonNull List<ScanResult> scanResults) {
+ checkNotNull(scanResults, "Scan Result list should not be null!");
+
+ // Group scans by StandardWifiEntry key
+ final Map<String, List<ScanResult>> scanResultsByKey = scanResults.stream()
+ .filter(scanResult -> !TextUtils.isEmpty(scanResult.SSID))
+ .collect(groupingBy(StandardWifiEntry::scanResultToStandardWifiEntryKey));
+
+ // Iterate through current entries and update each entry's scan results
+ mStandardWifiEntryCache.entrySet().forEach(entry -> {
+ final String key = entry.getKey();
+ final StandardWifiEntry wifiEntry = entry.getValue();
+ // Update scan results if available, or set to null.
+ wifiEntry.updateScanResultInfo(scanResultsByKey.get(key));
+ });
+ }
+
+ /**
+ * Conditionally updates the WifiEntry scan results based on the current wifi state and
+ * whether the last scan succeeded or not.
+ */
+ @WorkerThread
+ private void conditionallyUpdateScanResults(boolean lastScanSucceeded) {
+ if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) {
+ updateStandardWifiEntryScans(Collections.emptyList());
+ return;
+ }
+
+ long scanAgeWindow = mMaxScanAgeMillis;
+ if (lastScanSucceeded) {
+ // Scan succeeded, cache new scans
+ mScanResultUpdater.update(mWifiManager.getScanResults());
+ } else {
+ // Scan failed, increase scan age window to prevent WifiEntry list from
+ // clearing prematurely.
+ scanAgeWindow += mScanIntervalMillis;
+ }
+ updateStandardWifiEntryScans(mScanResultUpdater.getScanResults(scanAgeWindow));
+ }
+
+ /**
+ * Updates or removes a WifiConfiguration for the corresponding StandardWifiEntry if it exists.
+ *
+ * If an entry does not exist and the changeReason is ADDED or UPDATED, then a new entry will
+ * be created for the new config.
+ *
+ * @param config WifiConfiguration to update
+ * @param changeReason WifiManager.CHANGE_REASON_ADDED, WifiManager.CHANGE_REASON_REMOVED, or
+ * WifiManager.CHANGE_REASON_CONFIG_CHANGE
+ */
+ @WorkerThread
+ private void updateStandardWifiEntryConfig(@NonNull WifiConfiguration config,
+ int changeReason) {
+ checkNotNull(config, "Config should not be null!");
+
+ final String key = wifiConfigToStandardWifiEntryKey(config);
+ final StandardWifiEntry entry = mStandardWifiEntryCache.get(key);
+
+ if (entry != null) {
+ if (changeReason == WifiManager.CHANGE_REASON_REMOVED) {
+ entry.updateConfig(null);
+ mStandardWifiEntryCache.remove(key);
+ } else { // CHANGE_REASON_ADDED || CHANGE_REASON_CONFIG_CHANGE
+ entry.updateConfig(config);
+ }
+ } else {
+ if (changeReason != WifiManager.CHANGE_REASON_REMOVED) {
+ mStandardWifiEntryCache.put(key, new StandardWifiEntry(mMainHandler, config));
+ }
+ }
+ }
+
+ private void updateStandardWifiEntryConfigs(@NonNull List<WifiConfiguration> configs) {
+ checkNotNull(configs, "Config list should not be null!");
+
+ // Group configs by StandardWifiEntry key
+ final Map<String, WifiConfiguration> wifiConfigsByKey =
+ configs.stream().collect(Collectors.toMap(
+ StandardWifiEntry::wifiConfigToStandardWifiEntryKey,
+ Function.identity()));
+
+ // Iterate through current entries and update each entry's config
+ mStandardWifiEntryCache.entrySet().removeIf((entry) -> {
+ final StandardWifiEntry wifiEntry = entry.getValue();
+ final String key = wifiEntry.getKey();
+ // Update config if available, or set to null (unsaved)
+ wifiEntry.updateConfig(wifiConfigsByKey.remove(key));
+ // Entry is now unsaved, remove it.
+ return !wifiEntry.isSaved();
+ });
+
+ // Create new entry for each unmatched config
+ for (String key : wifiConfigsByKey.keySet()) {
+ mStandardWifiEntryCache.put(key,
+ new StandardWifiEntry(mMainHandler, wifiConfigsByKey.get(key)));
+ }
+ }
+
+ /**
+ * Posts onSavedWifiEntriesChanged callback on the main thread.
+ */
+ @WorkerThread
+ private void notifyOnSavedWifiEntriesChanged() {
+ if (mListener != null) {
+ mMainHandler.post(mListener::onSavedWifiEntriesChanged);
+ }
+ }
+
+ /**
+ * Posts onSubscriptionWifiEntriesChanged callback on the main thread.
+ */
+ @WorkerThread
+ private void notifyOnSubscriptionWifiEntriesChanged() {
+ if (mListener != null) {
+ mMainHandler.post(mListener::onSubscriptionWifiEntriesChanged);
+ }
+ }
+
+ /**
+ * Listener for changes to the list of saved and subscription WifiEntries
+ *
+ * These callbacks must be run on the MainThread.
+ */
+ public interface SavedNetworkTrackerCallback extends BaseWifiTracker.BaseWifiTrackerCallback {
+ /**
+ * Called when there are changes to
+ * {@link #getSavedWifiEntries()}
+ */
+ @MainThread
+ void onSavedWifiEntriesChanged();
+
+ /**
+ * Called when there are changes to
+ * {@link #getSubscriptionWifiEntries()}
+ */
+ @MainThread
+ void onSubscriptionWifiEntriesChanged();
+ }
+}
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
index 54076dbe1..fbebd93f6 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
@@ -56,7 +56,7 @@ class StandardWifiEntry extends WifiEntry {
StandardWifiEntry(@NonNull Handler callbackHandler, @NonNull List<ScanResult> scanResults)
throws IllegalArgumentException {
- super(callbackHandler);
+ super(callbackHandler, false /* forSavedNetworksPage */);
checkNotNull(scanResults, "Cannot construct with null ScanResult list!");
if (scanResults.isEmpty()) {
@@ -71,7 +71,7 @@ class StandardWifiEntry extends WifiEntry {
StandardWifiEntry(@NonNull Handler callbackHandler, @NonNull WifiConfiguration config)
throws IllegalArgumentException {
- super(callbackHandler);
+ super(callbackHandler, true /* forSavedNetworksPage */);
checkNotNull(config, "Cannot construct with null config!");
checkNotNull(config.SSID, "Supplied config must have an SSID!");
@@ -102,6 +102,8 @@ class StandardWifiEntry extends WifiEntry {
@Override
public String getSummary() {
// TODO(b/70983952): Fill this method in
+ if (mForSavedNetworksPage) return null;
+
if (isSaved()) return "Saved"; // Placeholder for visual verification
return null;
}
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
index 94fbdf278..aa8ece7fa 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java
@@ -126,13 +126,17 @@ public abstract class WifiEntry implements Comparable<WifiEntry> {
public static final int FREQUENCY_6_GHZ = 6_000;
public static final int FREQUENCY_UNKNOWN = -1;
+ protected final boolean mForSavedNetworksPage;
+
// Callback associated with this WifiEntry. Subclasses should call its methods appropriately.
private WifiEntryCallback mListener;
private Handler mCallbackHandler;
- WifiEntry(@NonNull Handler callbackHandler) throws IllegalArgumentException {
+ WifiEntry(@NonNull Handler callbackHandler, boolean forSavedNetworksPage)
+ throws IllegalArgumentException {
checkNotNull(callbackHandler, "Cannot construct with null handler!");
mCallbackHandler = callbackHandler;
+ mForSavedNetworksPage = forSavedNetworksPage;
}
// Info available for all WifiEntries //
diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/SavedNetworkTrackerTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/SavedNetworkTrackerTest.java
new file mode 100644
index 000000000..e7e7cbde1
--- /dev/null
+++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/SavedNetworkTrackerTest.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2019 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.wifitrackerlib;
+
+import static com.android.wifitrackerlib.TestUtils.buildScanResult;
+import static com.android.wifitrackerlib.TestUtils.buildWifiConfiguration;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkScoreManager;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.test.TestLooper;
+
+import androidx.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.time.Clock;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+public class SavedNetworkTrackerTest {
+
+ private static final long START_MILLIS = 123_456_789;
+
+ private static final long MAX_SCAN_AGE_MILLIS = 15_000;
+ private static final long SCAN_INTERVAL_MILLIS = 10_000;
+
+ @Mock
+ private Lifecycle mMockLifecycle;
+ @Mock
+ private Context mMockContext;
+ @Mock
+ private WifiManager mMockWifiManager;
+ @Mock
+ private ConnectivityManager mMockConnectivityManager;
+ @Mock
+ private NetworkScoreManager mMockNetworkScoreManager;
+ @Mock
+ private Clock mMockClock;
+ @Mock
+ private SavedNetworkTracker.SavedNetworkTrackerCallback mMockCallback;
+
+ private TestLooper mTestLooper;
+
+ private final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+
+ private SavedNetworkTracker createTestSavedNetworkTracker() {
+ final Handler testHandler = new Handler(mTestLooper.getLooper());
+
+ return new SavedNetworkTracker(mMockLifecycle, mMockContext,
+ mMockWifiManager,
+ mMockConnectivityManager,
+ mMockNetworkScoreManager,
+ testHandler,
+ testHandler,
+ mMockClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ mMockCallback);
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mTestLooper = new TestLooper();
+
+ when(mMockWifiManager.getScanResults()).thenReturn(new ArrayList<>());
+ when(mMockClock.millis()).thenReturn(START_MILLIS);
+ }
+
+ /**
+ * Tests that the wifi state is set correctly after onStart, even if no broadcast was received.
+ */
+ @Test
+ public void testOnStart_setsWifiState() {
+ final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
+
+ // Set the wifi state to disabled
+ when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
+ savedNetworkTracker.onStart();
+ mTestLooper.dispatchAll();
+
+ assertThat(savedNetworkTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_DISABLED);
+
+ // Change the wifi state to enabled
+ savedNetworkTracker.onStop();
+ when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
+ savedNetworkTracker.onStart();
+ mTestLooper.dispatchAll();
+
+ assertThat(savedNetworkTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED);
+ }
+
+ /**
+ * Tests that receiving a wifi state change broadcast updates getWifiState().
+ */
+ @Test
+ public void testWifiStateChangeBroadcast_updatesWifiState() {
+ final SavedNetworkTracker wifiPickerTracker = createTestSavedNetworkTracker();
+ wifiPickerTracker.onStart();
+ verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
+ any(), any(), any());
+
+ // Set the wifi state to disabled
+ when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
+ mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
+ new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
+
+ assertThat(wifiPickerTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_DISABLED);
+
+ // Change the wifi state to enabled
+ when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
+ mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
+ new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
+
+ assertThat(wifiPickerTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED);
+ }
+
+ /**
+ * Tests that receiving a wifi state change broadcast notifies the listener.
+ */
+ @Test
+ public void testWifiStateChangeBroadcast_notifiesListener() {
+ final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
+ savedNetworkTracker.onStart();
+ verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
+ any(), any(), any());
+
+ mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
+ new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
+ mTestLooper.dispatchAll();
+
+ verify(mMockCallback, atLeastOnce()).onWifiStateChanged();
+ }
+
+ /**
+ * Tests that a CONFIGURED_NETWORKS_CHANGED broadcast notifies the listener for
+ * onSavedWifiEntriesChanged().
+ */
+ @Test
+ public void testConfiguredNetworksChanged_notifiesListener() {
+ final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
+ savedNetworkTracker.onStart();
+ verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
+ any(), any(), any());
+
+ mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
+ new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
+ mTestLooper.dispatchAll();
+
+ verify(mMockCallback, atLeastOnce()).onSavedWifiEntriesChanged();
+ }
+
+ /**
+ * Tests that a WifiEntry is created for each configured network for getSavedWifiEntries().
+ */
+ @Test
+ public void testGetSavedWifiEntries_onStart_entryForEachConfiguredNetwork() {
+ when(mMockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(
+ buildWifiConfiguration("ssid0"),
+ buildWifiConfiguration("ssid1"),
+ buildWifiConfiguration("ssid2")
+ ));
+ final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
+ savedNetworkTracker.onStart();
+ verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
+ any(), any(), any());
+ mTestLooper.dispatchAll();
+
+ assertThat(savedNetworkTracker.getSavedWifiEntries().stream().map(WifiEntry::getTitle)
+ .collect(Collectors.toSet()))
+ .containsExactly("ssid0", "ssid1", "ssid2");
+ }
+
+ /**
+ * Tests that a CONFIGURED_NETWORKS_CHANGED broadcast with CHANGE_REASON_ADDED
+ * adds the corresponding WifiEntry from getSavedWifiEntries().
+ */
+ @Test
+ public void testGetSavedWifiEntries_configuredNetworksChanged_addsEntry() {
+ final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
+ savedNetworkTracker.onStart();
+ verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
+ any(), any(), any());
+ mTestLooper.dispatchAll();
+
+ assertThat(savedNetworkTracker.getSavedWifiEntries()).isEmpty();
+
+ mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
+ new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION)
+ .putExtra(WifiManager.EXTRA_WIFI_CONFIGURATION,
+ buildWifiConfiguration("ssid"))
+ .putExtra(WifiManager.EXTRA_CHANGE_REASON,
+ WifiManager.CHANGE_REASON_ADDED));
+
+ assertThat(savedNetworkTracker.getSavedWifiEntries()).hasSize(1);
+ }
+
+ /**
+ * Tests that a CONFIGURED_NETWORKS_CHANGED broadcast with CHANGE_REASON_REMOVED
+ * removes the corresponding WifiEntry from getSavedWifiEntries().
+ */
+ @Test
+ public void testGetSavedWifiEntries_configuredNetworksChanged_removesEntry() {
+ final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
+ final WifiConfiguration config = buildWifiConfiguration("ssid");
+ when(mMockWifiManager.getConfiguredNetworks())
+ .thenReturn(Collections.singletonList(config));
+ savedNetworkTracker.onStart();
+ verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
+ any(), any(), any());
+ mTestLooper.dispatchAll();
+
+ assertThat(savedNetworkTracker.getSavedWifiEntries()).hasSize(1);
+
+ mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
+ new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION)
+ .putExtra(WifiManager.EXTRA_WIFI_CONFIGURATION, config)
+ .putExtra(WifiManager.EXTRA_CHANGE_REASON,
+ WifiManager.CHANGE_REASON_REMOVED));
+
+ assertThat(savedNetworkTracker.getSavedWifiEntries()).isEmpty();
+ }
+
+ /**
+ * Tests that receiving a scan results available broadcast notifies the listener.
+ */
+ @Test
+ public void testScanResultsAvailableAction_notifiesListener() {
+ final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
+ savedNetworkTracker.onStart();
+ verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
+ any(), any(), any());
+
+ mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
+ new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
+ mTestLooper.dispatchAll();
+
+ verify(mMockCallback, atLeastOnce()).onSavedWifiEntriesChanged();
+ }
+
+ /**
+ * Tests that the scan results available broadcast changes the level of saved WifiEntries.
+ */
+ @Test
+ public void testGetSavedWifiEntries_scanResultsAvailableAction_changesLevel() {
+ final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
+ final WifiConfiguration config = buildWifiConfiguration("ssid");
+ when(mMockWifiManager.getConfiguredNetworks())
+ .thenReturn(Collections.singletonList(config));
+ savedNetworkTracker.onStart();
+ verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
+ any(), any(), any());
+ mTestLooper.dispatchAll();
+ final WifiEntry entry = savedNetworkTracker.getSavedWifiEntries().get(0);
+
+ assertThat(entry.getLevel()).isEqualTo(WifiEntry.WIFI_LEVEL_UNREACHABLE);
+
+ when(mMockWifiManager.getScanResults()).thenReturn(Collections.singletonList(
+ buildScanResult("ssid", "bssid", START_MILLIS, -50 /* rssi */)));
+ mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
+ new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
+
+ assertThat(entry.getLevel()).isNotEqualTo(WifiEntry.WIFI_LEVEL_UNREACHABLE);
+
+ when(mMockClock.millis()).thenReturn(START_MILLIS + MAX_SCAN_AGE_MILLIS + 1);
+ mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
+ new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
+
+ assertThat(entry.getLevel()).isEqualTo(WifiEntry.WIFI_LEVEL_UNREACHABLE);
+ }
+}
diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/TestUtils.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/TestUtils.java
index 547a5721e..9f5b5433a 100644
--- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/TestUtils.java
+++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/TestUtils.java
@@ -17,6 +17,7 @@
package com.android.wifitrackerlib;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
/**
* Utility methods for testing purposes.
@@ -38,4 +39,10 @@ class TestUtils {
result.level = rssi;
return result;
}
+
+ static WifiConfiguration buildWifiConfiguration(String ssid) {
+ final WifiConfiguration config = new WifiConfiguration();
+ config.SSID = "\"" + ssid + "\"";
+ return config;
+ }
}
diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java
index 3fd18f98c..d298d4872 100644
--- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java
+++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/WifiPickerTrackerTest.java
@@ -70,14 +70,14 @@ public class WifiPickerTrackerTest {
@Mock
private Clock mMockClock;
@Mock
- private WifiPickerTracker.WifiPickerTrackerCallback mMockWifiTrackerCallback;
+ private WifiPickerTracker.WifiPickerTrackerCallback mMockCallback;
private TestLooper mTestLooper;
private final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
- private WifiPickerTracker createTestWifiTracker2() {
+ private WifiPickerTracker createTestWifiPickerTracker() {
final Handler testHandler = new Handler(mTestLooper.getLooper());
return new WifiPickerTracker(mMockLifecycle, mMockContext,
@@ -89,7 +89,7 @@ public class WifiPickerTrackerTest {
mMockClock,
MAX_SCAN_AGE_MILLIS,
SCAN_INTERVAL_MILLIS,
- mMockWifiTrackerCallback);
+ mMockCallback);
}
@Before
@@ -107,7 +107,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testWifiStateChangeBroadcast_updatesWifiState() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
@@ -133,7 +133,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testWifiStateChangeBroadcast_notifiesListener() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
@@ -142,7 +142,7 @@ public class WifiPickerTrackerTest {
new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
mTestLooper.dispatchAll();
- verify(mMockWifiTrackerCallback, atLeastOnce()).onWifiStateChanged();
+ verify(mMockCallback, atLeastOnce()).onWifiStateChanged();
}
/**
@@ -151,7 +151,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testConfiguredNetworksChanged_notifiesListener() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
@@ -160,7 +160,7 @@ public class WifiPickerTrackerTest {
new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
mTestLooper.dispatchAll();
- verify(mMockWifiTrackerCallback, atLeastOnce()).onNumSavedNetworksChanged();
+ verify(mMockCallback, atLeastOnce()).onNumSavedNetworksChanged();
}
/**
@@ -168,7 +168,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testOnStart_setsWifiState() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
// Set the wifi state to disabled
when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
@@ -191,7 +191,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testScanResultsAvailableAction_notifiesListener() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
@@ -200,7 +200,7 @@ public class WifiPickerTrackerTest {
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
mTestLooper.dispatchAll();
- verify(mMockWifiTrackerCallback, atLeastOnce()).onWifiEntriesChanged();
+ verify(mMockCallback, atLeastOnce()).onWifiEntriesChanged();
}
/**
@@ -208,7 +208,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testGetWifiEntries_noScans_emptyList() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
@@ -228,7 +228,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testGetWifiEntries_wifiNetworkEntries_createdForEachSsidAndSecurityPair() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
@@ -263,7 +263,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testGetWifiEntries_wifiNetworkEntries_oldEntriesTimedOut() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
@@ -300,7 +300,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testGetWifiEntries_wifiNetworkEntries_useOldEntriesOnFailedScan() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
@@ -340,7 +340,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testGetWifiEntries_configuredNetworksChanged_unsavedToSaved() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
wifiPickerTracker.onStart();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
@@ -370,7 +370,7 @@ public class WifiPickerTrackerTest {
*/
@Test
public void testGetWifiEntries_configuredNetworksChanged_savedToUnsaved() {
- final WifiPickerTracker wifiPickerTracker = createTestWifiTracker2();
+ final WifiPickerTracker wifiPickerTracker = createTestWifiPickerTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
when(mMockWifiManager.getConfiguredNetworks())