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 17package com.android.server.wifi; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertNotNull; 21import static org.junit.Assert.assertNull; 22import static org.mockito.Mockito.when; 23import static org.mockito.MockitoAnnotations.initMocks; 24 25import android.net.wifi.ScanResult; 26import android.net.wifi.WifiSsid; 27import android.test.suitebuilder.annotation.SmallTest; 28import android.util.Log; 29 30import com.android.server.wifi.anqp.ANQPElement; 31import com.android.server.wifi.anqp.Constants; 32import com.android.server.wifi.hotspot2.ANQPData; 33import com.android.server.wifi.hotspot2.AnqpCache; 34import com.android.server.wifi.hotspot2.NetworkDetail; 35 36import org.junit.Test; 37import org.mockito.Mock; 38 39import java.util.ArrayList; 40import java.util.Arrays; 41import java.util.HashMap; 42import java.util.List; 43import java.util.Map; 44 45 46/** 47 * Unit tests for {@link com.android.server.wifi.hotspot2.AnqpCache}. 48 */ 49@SmallTest 50public class AnqpCacheTest { 51 52 private static final String TAG = "AnqpCacheTest"; 53 54 private static class NetworkDescription { 55 ScanDetail[] mScanDetails; 56 static int[] sChannels = new int[]{2412, 2437, 2462, 5180, 5220, 5745, 5825}; 57 static int[] sRSSIs = new int[]{ -50, -80, -60, -80, -55, -90, -75}; 58 59 NetworkDescription(String ssid, String bssidPrefix) { 60 WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(ssid); 61 mScanDetails = new ScanDetail[sChannels.length]; 62 for (int i = 0; i < sChannels.length; i++) { 63 String bssid = String.format("%s:%02x", bssidPrefix, i); 64 ScanResult.InformationElement[] ie = new ScanResult.InformationElement[1]; 65 ie[0] = ScanResults.generateSsidIe(ssid); 66 List<String> anqpLines = new ArrayList<String>(); 67 NetworkDetail nd = new NetworkDetail(bssid, ie, 68 new ArrayList<String>(), sChannels[i]); 69 mScanDetails[i] = new ScanDetail(nd, wifiSsid, 70 bssid, "", sRSSIs[i], sChannels[i], Long.MAX_VALUE, ie, anqpLines); 71 } 72 } 73 } 74 75 private static final String ATT_SSID = "att_wifi"; 76 private static final String ATT_BSSID_PREFIX = "aa:44:bb:55:cc"; 77 private static final String TWC_SSID = "TWCWIFI"; 78 private static final String TWC_BSSID_PREFIX = "11:aa:22:bb:33"; 79 80 private static ScanDetail[] getAttWifiNetworkDescription() { 81 NetworkDescription network = new NetworkDescription(ATT_SSID, ATT_BSSID_PREFIX); 82 return network.mScanDetails; 83 } 84 85 private static ScanDetail[] getTwcWifiNetworkDescription() { 86 NetworkDescription network = new NetworkDescription(TWC_SSID, TWC_BSSID_PREFIX); 87 return network.mScanDetails; 88 } 89 90 private static List<Constants.ANQPElementType> buildQueryList() { 91 List<Constants.ANQPElementType> list = Arrays.asList( 92 Constants.ANQPElementType.class.getEnumConstants()); 93 return list; 94 } 95 96 private static Map<Constants.ANQPElementType, ANQPElement> buildAnqpResult() { 97 Map<Constants.ANQPElementType, ANQPElement> elements = new HashMap<>(); 98 List<Constants.ANQPElementType> list = Arrays.asList( 99 Constants.ANQPElementType.class.getEnumConstants()); 100 for (final Constants.ANQPElementType type : list) { 101 ANQPElement element = new ANQPElement(type) { 102 @Override 103 public Constants.ANQPElementType getID() { 104 return super.getID(); 105 } 106 }; 107 elements.put(type, element); 108 } 109 110 return elements; 111 } 112 113 private void advanceTimeAndTrimCache(long howManyMillis) { 114 mCurrentTimeMillis += howManyMillis; 115 Log.d(TAG, "Time set to " + mCurrentTimeMillis); 116 when(mClock.currentTimeMillis()).thenReturn(mCurrentTimeMillis); 117 mCache.clear(false, true); 118 } 119 120 public AnqpCacheTest() {} 121 122 private static final long SECOND_MS = 1000; 123 private static final long MINUTE_MS = 60 * SECOND_MS; 124 125 @Mock Clock mClock; 126 long mCurrentTimeMillis = 1000000000; 127 AnqpCache mCache; 128 129 /** verify that ANQP data is cached per the (rather abstract) spec */ 130 @Test 131 public void basicAddQueryAndExpiry() { 132 initMocks(this); 133 134 AnqpCache cache = mCache = new AnqpCache(mClock); 135 advanceTimeAndTrimCache(0); 136 137 List<Constants.ANQPElementType> queryList = buildQueryList(); 138 139 ScanDetail[] attScanDetails = getAttWifiNetworkDescription(); 140 ScanDetail[] twcScanDetails = getTwcWifiNetworkDescription(); 141 142 /* query att network at time 0 */ 143 for (ScanDetail scanDetail : attScanDetails) { 144 cache.initiate(scanDetail.getNetworkDetail(), queryList); 145 } 146 147 /* verify that no data can be returned */ 148 for (ScanDetail scanDetail : attScanDetails) { 149 ANQPData data = cache.getEntry(scanDetail.getNetworkDetail()); 150 assertNull(data); 151 } 152 153 /* update ANQP results after 1 min */ 154 advanceTimeAndTrimCache(1 * MINUTE_MS); 155 156 Map<Constants.ANQPElementType, ANQPElement> anqpResults = buildAnqpResult(); 157 158 for (ScanDetail scanDetail : attScanDetails) { 159 cache.update(scanDetail.getNetworkDetail(), anqpResults); 160 } 161 162 /* check ANQP results after another 1 min */ 163 advanceTimeAndTrimCache(1 * MINUTE_MS); 164 165 for (ScanDetail scanDetail : attScanDetails) { 166 ANQPData data = cache.getEntry(scanDetail.getNetworkDetail()); 167 assertNotNull(data); 168 NetworkDetail nd = data.getNetwork(); 169 Map<Constants.ANQPElementType, ANQPElement> anqp = data.getANQPElements(); 170 assertEquals(scanDetail.getBSSIDString(), nd.getBSSIDString()); 171 assertEquals(anqpResults.size(), anqp.size()); 172 } 173 174 /* query ANQP results for twcwifi after another 10 min */ 175 advanceTimeAndTrimCache(10 * MINUTE_MS); 176 177 for (ScanDetail scanDetail : twcScanDetails) { 178 cache.initiate(scanDetail.getNetworkDetail(), queryList); 179 } 180 181 /* update ANQP results for twcwifi after another 10 min */ 182 advanceTimeAndTrimCache(1 * MINUTE_MS); 183 184 for (ScanDetail scanDetail : twcScanDetails) { 185 cache.update(scanDetail.getNetworkDetail(), anqpResults); 186 } 187 188 /* check all results after 1 minute */ 189 advanceTimeAndTrimCache(1 * MINUTE_MS); 190 191 for (ScanDetail scanDetail : attScanDetails) { 192 ANQPData data = cache.getEntry(scanDetail.getNetworkDetail()); 193 assertNull(data); 194 } 195 196 for (ScanDetail scanDetail : twcScanDetails) { 197 ANQPData data = cache.getEntry(scanDetail.getNetworkDetail()); 198 assertNotNull(data); 199 NetworkDetail nd = data.getNetwork(); 200 Map<Constants.ANQPElementType, ANQPElement> anqp = data.getANQPElements(); 201 assertEquals(scanDetail.getBSSIDString(), nd.getBSSIDString()); 202 assertEquals(anqpResults.size(), anqp.size()); 203 } 204 } 205} 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237