summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xwifi/java/android/net/wifi/WifiNetworkScoreCache.java63
-rw-r--r--wifi/tests/Android.mk13
-rw-r--r--wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java58
3 files changed, 81 insertions, 53 deletions
diff --git a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
index f61dfdc2f6f9..b22ae07015c8 100755
--- a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
+++ b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
@@ -26,15 +26,14 @@ import android.net.ScoredNetwork;
import android.os.Handler;
import android.os.Process;
import android.util.Log;
+import android.util.LruCache;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* {@link INetworkScoreCache} implementation for Wifi Networks.
@@ -50,18 +49,21 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
// scorer to provide an RSSI threshold below which a network should not be used.
public static final int INVALID_NETWORK_SCORE = Byte.MIN_VALUE;
+ /** Default number entries to be stored in the {@link LruCache}. */
+ private static final int DEFAULT_MAX_CACHE_SIZE = 100;
+
// See {@link #CacheListener}.
@Nullable
- @GuardedBy("mCacheLock")
+ @GuardedBy("mLock")
private CacheListener mListener;
private final Context mContext;
- private final Object mCacheLock = new Object();
+ private final Object mLock = new Object();
// The key is of the form "<ssid>"<bssid>
// TODO: What about SSIDs that can't be encoded as UTF-8?
- private final Map<String, ScoredNetwork> mNetworkCache;
-
+ @GuardedBy("mLock")
+ private final LruCache<String, ScoredNetwork> mCache;
public WifiNetworkScoreCache(Context context) {
this(context, null /* listener */);
@@ -74,9 +76,14 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
* @param listener CacheListener for cache updates
*/
public WifiNetworkScoreCache(Context context, @Nullable CacheListener listener) {
+ this(context, listener, DEFAULT_MAX_CACHE_SIZE);
+ }
+
+ public WifiNetworkScoreCache(
+ Context context, @Nullable CacheListener listener, int maxCacheSize) {
mContext = context.getApplicationContext();
mListener = listener;
- mNetworkCache = new HashMap<>();
+ mCache = new LruCache<>(maxCacheSize);
}
@Override public final void updateScores(List<ScoredNetwork> networks) {
@@ -89,7 +96,7 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
boolean changed = false;
- synchronized(mNetworkCache) {
+ synchronized(mLock) {
for (ScoredNetwork network : networks) {
String networkKey = buildNetworkKey(network);
if (networkKey == null) {
@@ -98,12 +105,10 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
}
continue;
}
- mNetworkCache.put(networkKey, network);
+ mCache.put(networkKey, network);
changed = true;
}
- }
- synchronized (mCacheLock) {
if (mListener != null && changed) {
mListener.post(networks);
}
@@ -111,8 +116,8 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
}
@Override public final void clearScores() {
- synchronized (mNetworkCache) {
- mNetworkCache.clear();
+ synchronized (mLock) {
+ mCache.evictAll();
}
}
@@ -138,7 +143,6 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
}
public int getNetworkScore(ScanResult result) {
-
int score = INVALID_NETWORK_SCORE;
ScoredNetwork network = getScoredNetwork(result);
@@ -164,7 +168,6 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
}
public int getNetworkScore(ScanResult result, boolean isActiveNetwork) {
-
int score = INVALID_NETWORK_SCORE;
ScoredNetwork network = getScoredNetwork(result);
@@ -185,8 +188,8 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
String key = buildNetworkKey(result);
if (key == null) return null;
- synchronized(mNetworkCache) {
- ScoredNetwork network = mNetworkCache.get(key);
+ synchronized(mLock) {
+ ScoredNetwork network = mCache.get(key);
return network;
}
}
@@ -201,8 +204,8 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
}
return null;
}
- synchronized (mNetworkCache) {
- return mNetworkCache.get(key);
+ synchronized (mLock) {
+ return mCache.get(key);
}
}
@@ -248,33 +251,35 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
mContext.getPackageName(), Process.myUid());
writer.println(header);
writer.println(" All score curves:");
- for (ScoredNetwork score : mNetworkCache.values()) {
- writer.println(" " + score);
- }
- writer.println(" Current network scores:");
- WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- for (ScanResult scanResult : wifiManager.getScanResults()) {
- writer.println(" " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult));
+ synchronized (mLock) {
+ for (ScoredNetwork score : mCache.snapshot().values()) {
+ writer.println(" " + score);
+ }
+ writer.println(" Network scores for latest ScanResults:");
+ WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ for (ScanResult scanResult : wifiManager.getScanResults()) {
+ writer.println(
+ " " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult));
+ }
}
}
/** Registers a CacheListener instance, replacing the previous listener if it existed. */
public void registerListener(CacheListener listener) {
- synchronized (mCacheLock) {
+ synchronized (mLock) {
mListener = listener;
}
}
/** Removes the registered CacheListener. */
public void unregisterListener() {
- synchronized (mCacheLock) {
+ synchronized (mLock) {
mListener = null;
}
}
/** Listener for updates to the cache inside WifiNetworkScoreCache. */
public abstract static class CacheListener {
-
private Handler mHandler;
/**
diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk
index afab1a3721db..c98e40a2c2d9 100644
--- a/wifi/tests/Android.mk
+++ b/wifi/tests/Android.mk
@@ -49,14 +49,15 @@ LOCAL_JACK_COVERAGE_INCLUDE_FILTER := $(jacoco_include)
LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test \
- core-test-rules \
- guava \
- mockito-target-minus-junit4 \
- frameworks-base-testutils \
+ android-support-test \
+ core-test-rules \
+ guava \
+ mockito-target-minus-junit4 \
+ frameworks-base-testutils \
+ truth-prebuilt \
LOCAL_JAVA_LIBRARIES := \
- android.test.runner \
+ android.test.runner \
LOCAL_PACKAGE_NAME := FrameworksWifiApiTests
LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
index 18f6bc848081..997282b24b46 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkScoreCacheTest.java
@@ -16,9 +16,9 @@
package android.net.wifi;
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -34,12 +34,9 @@ import android.support.test.runner.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
-import org.junit.Rule;
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;
@@ -54,7 +51,11 @@ import java.util.concurrent.TimeUnit;
public class WifiNetworkScoreCacheTest {
public static final String SSID = "ssid";
+ public static final String SSID2 = "ssid2";
+ public static final String SSID3 = "ssid3";
public static final String FORMATTED_SSID = "\"" + SSID + "\"";
+ public static final String FORMATTED_SSID2 = "\"" + SSID2 + "\"";
+ public static final String FORMATTED_SSID3 = "\"" + SSID3 + "\"";
public static final String BSSID = "AA:AA:AA:AA:AA:AA";
public static final WifiKey VALID_KEY = new WifiKey(FORMATTED_SSID, BSSID);
@@ -120,13 +121,13 @@ public class WifiNetworkScoreCacheTest {
@Test
public void isScoredNetworkShouldReturnTrueAfterUpdateScoresIsCalled() {
- assertTrue(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT));
+ assertThat(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT)).isTrue();
}
@Test
public void isScoredNetworkShouldReturnFalseAfterClearScoresIsCalled() {
mScoreCache.clearScores();
- assertFalse(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT));
+ assertThat(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT)).isFalse();
}
@Test
@@ -137,19 +138,19 @@ public class WifiNetworkScoreCacheTest {
mScoreCache.updateScores(ImmutableList.of(network2));
- assertTrue(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT));
- assertTrue(mScoreCache.isScoredNetwork(result2));
+ assertThat(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT)).isTrue();
+ assertThat(mScoreCache.isScoredNetwork(result2)).isTrue();
}
@Test
public void hasScoreCurveShouldReturnTrue() {
- assertTrue(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT));
+ assertThat(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT)).isTrue();
}
@Test
public void hasScoreCurveShouldReturnFalseWhenNoCachedNetwork() {
ScanResult unscored = buildScanResult("fake", BSSID);
- assertFalse(mScoreCache.hasScoreCurve(unscored));
+ assertThat(mScoreCache.hasScoreCurve(unscored)).isFalse();
}
@Test
@@ -157,7 +158,7 @@ public class WifiNetworkScoreCacheTest {
ScoredNetwork noCurve = buildScoredNetwork(VALID_KEY, null /* rssiCurve */);
mScoreCache.updateScores(ImmutableList.of(noCurve));
- assertFalse(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT));
+ assertThat(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT)).isFalse();
}
@Test
@@ -169,12 +170,12 @@ public class WifiNetworkScoreCacheTest {
when(mockRssiCurve.lookupScore(rssi)).thenReturn(score);
- assertEquals(score, mScoreCache.getNetworkScore(result));
+ assertThat(mScoreCache.getNetworkScore(result)).isEqualTo(score);
}
@Test
public void getMeteredHintShouldReturnFalse() {
- assertFalse(mScoreCache.getMeteredHint(VALID_SCAN_RESULT));
+ assertThat(mScoreCache.getMeteredHint(VALID_SCAN_RESULT)).isFalse();
}
@Test
@@ -184,7 +185,7 @@ public class WifiNetworkScoreCacheTest {
new NetworkKey(VALID_KEY), mockRssiCurve, true /* metered Hint */);
mScoreCache.updateScores(ImmutableList.of(network));
- assertTrue(mScoreCache.getMeteredHint(VALID_SCAN_RESULT));
+ assertThat(mScoreCache.getMeteredHint(VALID_SCAN_RESULT)).isTrue();
}
@Test
@@ -197,7 +198,28 @@ public class WifiNetworkScoreCacheTest {
} catch (InterruptedException e) {
fail("Interrupted Exception while waiting for listener to be invoked.");
}
- assertEquals("One network should be updated", 1, mUpdatedNetworksCaptor.size());
- assertEquals(mValidScoredNetwork, mUpdatedNetworksCaptor.get(0));
+ // One network should be updated.
+ assertThat(mUpdatedNetworksCaptor.size()).isEqualTo(1);
+ assertThat(mUpdatedNetworksCaptor.get(0)).isEqualTo(mValidScoredNetwork);
+ }
+
+ @Test
+ public void leastRecentlyUsedScore_shouldBeEvictedFromCache() {
+ mScoreCache = new WifiNetworkScoreCache(mockContext, mCacheListener, 2 /* maxCacheSize */);
+
+ ScoredNetwork network1 = mValidScoredNetwork;
+ ScoredNetwork network2 = buildScoredNetwork(
+ new WifiKey(FORMATTED_SSID2, BSSID), mockRssiCurve);
+ ScoredNetwork network3 = buildScoredNetwork(
+ new WifiKey(FORMATTED_SSID3, BSSID), mockRssiCurve);
+ mScoreCache.updateScores(ImmutableList.of(network1));
+ mScoreCache.updateScores(ImmutableList.of(network2));
+
+ // First score should be evicted because max cache size has been reached.
+ mScoreCache.updateScores(ImmutableList.of(network3));
+
+ assertThat(mScoreCache.hasScoreCurve(buildScanResult(SSID2, BSSID))).isTrue();
+ assertThat(mScoreCache.hasScoreCurve(buildScanResult(SSID3, BSSID))).isTrue();
+ assertThat(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT)).isFalse();
}
}