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 org.junit.Assert.*; 20 import static org.mockito.Mockito.timeout; 21 import static org.mockito.Mockito.verify; 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 import android.support.test.filters.SmallTest; 33 import android.support.test.runner.AndroidJUnit4; 34 35 import com.google.common.collect.ImmutableList; 36 37 import org.junit.Rule; 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 import org.mockito.ArgumentCaptor; 42 import org.mockito.Captor; 43 import org.mockito.Mock; 44 import org.mockito.MockitoAnnotations; 45 46 import java.util.List; 47 import java.util.concurrent.CountDownLatch; 48 import java.util.concurrent.TimeUnit; 49 50 51 /** Unit tests for {@link WifiNetworkScoreCache}. */ 52 @RunWith(AndroidJUnit4.class) 53 @SmallTest 54 public class WifiNetworkScoreCacheTest { 55 56 public static final String SSID = "ssid"; 57 public static final String FORMATTED_SSID = "\"" + SSID + "\""; 58 public static final String BSSID = "AA:AA:AA:AA:AA:AA"; 59 60 public static final WifiKey VALID_KEY = new WifiKey(FORMATTED_SSID, BSSID); 61 62 public static final ScanResult VALID_SCAN_RESULT = buildScanResult(SSID, BSSID); 63 64 @Mock private Context mockApplicationContext; 65 @Mock private Context mockContext; // isn't used, can be null 66 @Mock private RssiCurve mockRssiCurve; 67 68 69 private CacheListener mCacheListener; 70 private CountDownLatch mLatch; 71 private Handler mHandler; 72 private List<ScoredNetwork> mUpdatedNetworksCaptor; 73 private ScoredNetwork mValidScoredNetwork; 74 private WifiNetworkScoreCache mScoreCache; 75 76 private static ScanResult buildScanResult(String ssid, String bssid) { 77 return new ScanResult( 78 WifiSsid.createFromAsciiEncoded(ssid), 79 bssid, 80 "" /* caps */, 81 0 /* level */, 82 0 /* frequency */, 83 0 /* tsf */, 84 0 /* distCm */, 85 0 /* distSdCm*/); 86 } 87 88 private static ScoredNetwork buildScoredNetwork(WifiKey key, RssiCurve curve) { 89 return new ScoredNetwork(new NetworkKey(key), curve); 90 } 91 92 // Called from setup 93 private void initializeCacheWithValidScoredNetwork() { 94 mScoreCache.updateScores(ImmutableList.of(mValidScoredNetwork)); 95 } 96 97 @Before 98 public void setUp() { 99 MockitoAnnotations.initMocks(this); 100 101 when(mockContext.getApplicationContext()).thenReturn(mockApplicationContext); 102 103 mValidScoredNetwork = buildScoredNetwork(VALID_KEY, mockRssiCurve); 104 mScoreCache = new WifiNetworkScoreCache(mockContext); 105 initializeCacheWithValidScoredNetwork(); 106 107 HandlerThread thread = new HandlerThread("WifiNetworkScoreCacheTest Handler Thread"); 108 thread.start(); 109 mHandler = new Handler(thread.getLooper()); 110 mLatch = new CountDownLatch(1); 111 mCacheListener = new CacheListener(mHandler) { 112 @Override 113 public void networkCacheUpdated(List<ScoredNetwork> updatedNetworks) { 114 mUpdatedNetworksCaptor = updatedNetworks; 115 mLatch.countDown(); 116 } 117 }; 118 } 119 120 121 @Test 122 public void isScoredNetworkShouldReturnTrueAfterUpdateScoresIsCalled() { 123 assertTrue(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT)); 124 } 125 126 @Test 127 public void isScoredNetworkShouldReturnFalseAfterClearScoresIsCalled() { 128 mScoreCache.clearScores(); 129 assertFalse(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT)); 130 } 131 132 @Test 133 public void updateScoresShouldAddNewNetwork() { 134 WifiKey key2 = new WifiKey("\"ssid2\"", BSSID); 135 ScoredNetwork network2 = buildScoredNetwork(key2, mockRssiCurve); 136 ScanResult result2 = buildScanResult("ssid2", BSSID); 137 138 mScoreCache.updateScores(ImmutableList.of(network2)); 139 140 assertTrue(mScoreCache.isScoredNetwork(VALID_SCAN_RESULT)); 141 assertTrue(mScoreCache.isScoredNetwork(result2)); 142 } 143 144 @Test 145 public void hasScoreCurveShouldReturnTrue() { 146 assertTrue(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT)); 147 } 148 149 @Test 150 public void hasScoreCurveShouldReturnFalseWhenNoCachedNetwork() { 151 ScanResult unscored = buildScanResult("fake", BSSID); 152 assertFalse(mScoreCache.hasScoreCurve(unscored)); 153 } 154 155 @Test 156 public void hasScoreCurveShouldReturnFalseWhenScoredNetworkHasNoCurve() { 157 ScoredNetwork noCurve = buildScoredNetwork(VALID_KEY, null /* rssiCurve */); 158 mScoreCache.updateScores(ImmutableList.of(noCurve)); 159 160 assertFalse(mScoreCache.hasScoreCurve(VALID_SCAN_RESULT)); 161 } 162 163 @Test 164 public void getNetworkScoreShouldReturnScore() { 165 final byte score = 50; 166 final int rssi = -70; 167 ScanResult result = new ScanResult(VALID_SCAN_RESULT); 168 result.level = rssi; 169 170 when(mockRssiCurve.lookupScore(rssi)).thenReturn(score); 171 172 assertEquals(score, mScoreCache.getNetworkScore(result)); 173 } 174 175 @Test 176 public void getMeteredHintShouldReturnFalse() { 177 assertFalse(mScoreCache.getMeteredHint(VALID_SCAN_RESULT)); 178 } 179 180 @Test 181 public void getMeteredHintShouldReturnTrue() { 182 ScoredNetwork network = 183 new ScoredNetwork( 184 new NetworkKey(VALID_KEY), mockRssiCurve, true /* metered Hint */); 185 mScoreCache.updateScores(ImmutableList.of(network)); 186 187 assertTrue(mScoreCache.getMeteredHint(VALID_SCAN_RESULT)); 188 } 189 190 @Test 191 public void updateScoresShouldInvokeCacheListener_networkCacheUpdated() { 192 mScoreCache = new WifiNetworkScoreCache(mockContext, mCacheListener); 193 initializeCacheWithValidScoredNetwork(); 194 195 try { 196 mLatch.await(1, TimeUnit.SECONDS); // wait for listener to be executed 197 } catch (InterruptedException e) { 198 fail("Interrupted Exception while waiting for listener to be invoked."); 199 } 200 assertEquals("One network should be updated", 1, mUpdatedNetworksCaptor.size()); 201 assertEquals(mValidScoredNetwork, mUpdatedNetworksCaptor.get(0)); 202 } 203 } 204