• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net.wifi;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.fail;
22 import static org.mockito.Mockito.when;
23 
24 import android.content.Context;
25 import android.net.NetworkKey;
26 import android.net.RssiCurve;
27 import android.net.ScoredNetwork;
28 import android.net.WifiKey;
29 import android.net.wifi.WifiNetworkScoreCache.CacheListener;
30 import android.os.Handler;
31 import android.os.HandlerThread;
32 
33 import androidx.test.filters.SmallTest;
34 import androidx.test.runner.AndroidJUnit4;
35 
36 import com.google.common.collect.ImmutableList;
37 
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 import org.mockito.Mock;
42 import org.mockito.MockitoAnnotations;
43 
44 import java.util.List;
45 import java.util.concurrent.CountDownLatch;
46 import java.util.concurrent.TimeUnit;
47 
48 /** Unit tests for {@link WifiNetworkScoreCache}. */
49 @RunWith(AndroidJUnit4.class)
50 @SmallTest
51 public class WifiNetworkScoreCacheTest {
52 
53     public static final String SSID = "ssid";
54     public static final String SSID2 = "ssid2";
55     public static final String SSID3 = "ssid3";
56     public static final String FORMATTED_SSID = "\"" + SSID + "\"";
57     public static final String FORMATTED_SSID2 = "\"" + SSID2 + "\"";
58     public static final String FORMATTED_SSID3 = "\"" + SSID3 + "\"";
59     public static final String BSSID = "AA:AA:AA:AA:AA:AA";
60 
61     public static final WifiKey VALID_KEY = new WifiKey(FORMATTED_SSID, BSSID);
62 
63     public static final ScanResult VALID_SCAN_RESULT = buildScanResult(SSID, BSSID);
64 
65     @Mock private Context mockApplicationContext;
66     @Mock private Context mockContext; // isn't used, can be null
67     @Mock private RssiCurve mockRssiCurve;
68 
69 
70     private CacheListener mCacheListener;
71     private CountDownLatch mLatch;
72     private Handler mHandler;
73     private List<ScoredNetwork> mUpdatedNetworksCaptor;
74     private ScoredNetwork mValidScoredNetwork;
75     private WifiNetworkScoreCache mScoreCache;
76 
buildScanResult(String ssid, String bssid)77     private static ScanResult buildScanResult(String ssid, String bssid) {
78         return new ScanResult(
79                 WifiSsid.fromUtf8Text(ssid),
80                 bssid,
81                 "" /* caps */,
82                 0 /* level */,
83                 0 /* frequency */,
84                 0 /* tsf */,
85                 0 /* distCm */,
86                 0 /* distSdCm*/);
87     }
88 
buildScoredNetwork(WifiKey key, RssiCurve curve)89     private static ScoredNetwork buildScoredNetwork(WifiKey key, RssiCurve curve) {
90         return new ScoredNetwork(new NetworkKey(key), curve);
91     }
92 
93     // Called from setup
initializeCacheWithValidScoredNetwork()94     private void initializeCacheWithValidScoredNetwork() {
95         mScoreCache.updateScores(ImmutableList.of(mValidScoredNetwork));
96     }
97 
98     @Before
setUp()99     public void setUp() {
100         MockitoAnnotations.initMocks(this);
101 
102         when(mockContext.getApplicationContext()).thenReturn(mockApplicationContext);
103 
104         mValidScoredNetwork = buildScoredNetwork(VALID_KEY, mockRssiCurve);
105         mScoreCache = new WifiNetworkScoreCache(mockContext);
106         initializeCacheWithValidScoredNetwork();
107 
108         HandlerThread thread = new HandlerThread("WifiNetworkScoreCacheTest Handler Thread");
109         thread.start();
110         mHandler = new Handler(thread.getLooper());
111         mLatch = new CountDownLatch(1);
112         mCacheListener = new CacheListener(mHandler) {
113             @Override
114             public void networkCacheUpdated(List<ScoredNetwork> updatedNetworks) {
115                 mUpdatedNetworksCaptor = updatedNetworks;
116                 mLatch.countDown();
117             }
118         };
119     }
120 
121 
122     @Test
isScoredNetworkShouldReturnTrueAfterUpdateScoresIsCalled()123     public void isScoredNetworkShouldReturnTrueAfterUpdateScoresIsCalled() {
124         assertThat(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT)).isTrue();
125     }
126 
127     @Test
isScoredNetworkShouldReturnFalseAfterClearScoresIsCalled()128     public void isScoredNetworkShouldReturnFalseAfterClearScoresIsCalled() {
129         mScoreCache.clearScores();
130         assertThat(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT)).isFalse();
131     }
132 
133     @Test
updateScoresShouldAddNewNetwork()134     public void updateScoresShouldAddNewNetwork() {
135         WifiKey key2 = new WifiKey("\"ssid2\"", BSSID);
136         ScoredNetwork network2 = buildScoredNetwork(key2, mockRssiCurve);
137         ScanResult result2 = buildScanResult("ssid2", BSSID);
138 
139         mScoreCache.updateScores(ImmutableList.of(network2));
140 
141         assertThat(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT)).isTrue();
142         assertThat(mScoreCache.isScoredNetwork(result2)).isTrue();
143     }
144 
145     @Test
hasScoreCurveShouldReturnTrue()146     public void hasScoreCurveShouldReturnTrue() {
147         assertThat(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT)).isTrue();
148     }
149 
150     @Test
hasScoreCurveShouldReturnFalseWhenNoCachedNetwork()151     public void hasScoreCurveShouldReturnFalseWhenNoCachedNetwork() {
152         ScanResult unscored = buildScanResult("fake", BSSID);
153         assertThat(mScoreCache.hasScoreCurve(unscored)).isFalse();
154     }
155 
156     @Test
hasScoreCurveShouldReturnFalseWhenScoredNetworkHasNoCurve()157     public void hasScoreCurveShouldReturnFalseWhenScoredNetworkHasNoCurve() {
158         ScoredNetwork noCurve = buildScoredNetwork(VALID_KEY, null /* rssiCurve */);
159         mScoreCache.updateScores(ImmutableList.of(noCurve));
160 
161         assertThat(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT)).isFalse();
162     }
163 
164     @Test
getNetworkScoreShouldReturnScore()165     public void getNetworkScoreShouldReturnScore() {
166         final byte score = 50;
167         final int rssi = -70;
168         ScanResult result = new ScanResult(VALID_SCAN_RESULT);
169         result.level = rssi;
170 
171         when(mockRssiCurve.lookupScore(rssi)).thenReturn(score);
172 
173         assertThat(mScoreCache.getNetworkScore(result)).isEqualTo(score);
174     }
175 
176     @Test
getMeteredHintShouldReturnFalse()177     public void getMeteredHintShouldReturnFalse() {
178         assertThat(mScoreCache.getMeteredHint(VALID_SCAN_RESULT)).isFalse();
179     }
180 
181     @Test
getMeteredHintShouldReturnTrue()182     public void getMeteredHintShouldReturnTrue() {
183         ScoredNetwork network =
184                 new ScoredNetwork(
185                     new NetworkKey(VALID_KEY), mockRssiCurve, true /* metered Hint */);
186         mScoreCache.updateScores(ImmutableList.of(network));
187 
188         assertThat(mScoreCache.getMeteredHint(VALID_SCAN_RESULT)).isTrue();
189     }
190 
191     @Test
updateScoresShouldInvokeCacheListener_networkCacheUpdated()192     public void updateScoresShouldInvokeCacheListener_networkCacheUpdated() {
193         mScoreCache = new WifiNetworkScoreCache(mockContext, mCacheListener);
194         initializeCacheWithValidScoredNetwork();
195 
196         try {
197             mLatch.await(1, TimeUnit.SECONDS); // wait for listener to be executed
198         } catch (InterruptedException e) {
199             fail("Interrupted Exception while waiting for listener to be invoked.");
200         }
201         // One network should be updated.
202         assertThat(mUpdatedNetworksCaptor.size()).isEqualTo(1);
203         assertThat(mUpdatedNetworksCaptor.get(0)).isEqualTo(mValidScoredNetwork);
204     }
205 
206     @Test
leastRecentlyUsedScore_shouldBeEvictedFromCache()207     public void leastRecentlyUsedScore_shouldBeEvictedFromCache() {
208         mScoreCache = new WifiNetworkScoreCache(mockContext, mCacheListener, 2 /* maxCacheSize */);
209 
210         ScoredNetwork network1 = mValidScoredNetwork;
211         ScoredNetwork network2 = buildScoredNetwork(
212                 new WifiKey(FORMATTED_SSID2, BSSID), mockRssiCurve);
213         ScoredNetwork network3 = buildScoredNetwork(
214                 new WifiKey(FORMATTED_SSID3, BSSID), mockRssiCurve);
215         mScoreCache.updateScores(ImmutableList.of(network1));
216         mScoreCache.updateScores(ImmutableList.of(network2));
217 
218         // First score should be evicted because max cache size has been reached.
219         mScoreCache.updateScores(ImmutableList.of(network3));
220 
221         assertThat(mScoreCache.hasScoreCurve(buildScanResult(SSID2, BSSID))).isTrue();
222         assertThat(mScoreCache.hasScoreCurve(buildScanResult(SSID3, BSSID))).isTrue();
223         assertThat(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT)).isFalse();
224     }
225 }
226