1 /*
2 * Copyright (C) 2020 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 #include "chre/pal/util/wifi_scan_cache.h"
18
19 #include <algorithm>
20 #include <cinttypes>
21 #include <cstring>
22
23 #include "chre/platform/linux/system_time.h"
24 #include "chre/platform/log.h"
25 #include "chre/platform/shared/pal_system_api.h"
26 #include "chre/util/fixed_size_vector.h"
27 #include "chre/util/macros.h"
28 #include "chre/util/nanoapp/wifi.h"
29 #include "chre/util/optional.h"
30 #include "chre/util/time.h"
31 #include "chre_api/chre/common.h"
32 #include "gtest/gtest.h"
33
34 using chre::Milliseconds;
35 using chre::Nanoseconds;
36 using chre::Seconds;
37 using chre::platform_linux::clearMonotonicTimeOverride;
38 using chre::platform_linux::overrideMonotonicTime;
39
40 namespace {
41
42 /************************************************
43 * Prototypes
44 ***********************************************/
45 void chreWifiScanResponseCallback(bool pending, uint8_t errorCode);
46 void chreWifiScanEventCallback(struct chreWifiScanEvent *event);
47
48 struct WifiScanResponse {
49 bool pending;
50 uint8_t errorCode;
51 };
52
53 /************************************************
54 * Global variables
55 ***********************************************/
56 const chrePalWifiCallbacks gChreWifiPalCallbacks = {
57 .scanResponseCallback = chreWifiScanResponseCallback,
58 .scanEventCallback = chreWifiScanEventCallback,
59 };
60
61 using InputVec = std::vector<chreWifiScanResult>;
62 using ResultVec = chre::FixedSizeVector<chreWifiScanResult,
63 CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY>;
64
65 chre::Optional<WifiScanResponse> gWifiScanResponse;
66 ResultVec gWifiScanResultList;
67 chre::Optional<chreWifiScanEvent> gExpectedWifiScanEvent;
68 bool gWifiScanEventCompleted;
69
70 /************************************************
71 * Test class
72 ***********************************************/
73 class WifiScanCacheTests : public ::testing::Test {
74 protected:
SetUp()75 void SetUp() override {
76 clearTestState();
77 EXPECT_TRUE(chreWifiScanCacheInit(&chre::gChrePalSystemApi,
78 &gChreWifiPalCallbacks));
79 }
80
TearDown()81 void TearDown() override {
82 chreWifiScanCacheDeinit();
83 clearMonotonicTimeOverride();
84 }
85
clearTestState()86 void clearTestState() {
87 gExpectedWifiScanEvent.reset();
88 gWifiScanResponse.reset();
89 while (!gWifiScanResultList.empty()) {
90 gWifiScanResultList.pop_back();
91 }
92 }
93 };
94
95 /************************************************
96 * Private functions
97 ***********************************************/
chreWifiScanResponseCallback(bool pending,uint8_t errorCode)98 void chreWifiScanResponseCallback(bool pending, uint8_t errorCode) {
99 WifiScanResponse response = {
100 .pending = pending,
101 .errorCode = errorCode,
102 };
103 gWifiScanResponse = response;
104 }
105
chreWifiScanEventCallback(struct chreWifiScanEvent * event)106 void chreWifiScanEventCallback(struct chreWifiScanEvent *event) {
107 ASSERT_TRUE(gExpectedWifiScanEvent.has_value());
108 EXPECT_EQ(event->version, gExpectedWifiScanEvent->version);
109 EXPECT_EQ(event->scanType, gExpectedWifiScanEvent->scanType);
110 EXPECT_EQ(event->ssidSetSize, gExpectedWifiScanEvent->ssidSetSize);
111 ASSERT_EQ(event->scannedFreqListLen,
112 gExpectedWifiScanEvent->scannedFreqListLen);
113 if (event->scannedFreqListLen > 0) {
114 ASSERT_NE(event->scannedFreqList, nullptr);
115 EXPECT_EQ(
116 memcmp(gExpectedWifiScanEvent->scannedFreqList, event->scannedFreqList,
117 event->scannedFreqListLen * sizeof(uint32_t)),
118 0);
119 }
120
121 EXPECT_EQ(event->radioChainPref, gExpectedWifiScanEvent->radioChainPref);
122 EXPECT_EQ(event->eventIndex, gExpectedWifiScanEvent->eventIndex);
123 gExpectedWifiScanEvent->eventIndex++;
124
125 for (uint8_t i = 0; i < event->resultCount; i++) {
126 const chreWifiScanResult &result = event->results[i];
127 gWifiScanResultList.push_back(result);
128 }
129
130 if (gWifiScanResultList.size() == event->resultTotal) {
131 gWifiScanEventCompleted = true;
132 }
133
134 chreWifiScanCacheReleaseScanEvent(event);
135 }
136
beginDefaultWifiCache(const uint32_t * scannedFreqList,uint16_t scannedFreqListLen,bool scanRequestedByChre=true)137 void beginDefaultWifiCache(const uint32_t *scannedFreqList,
138 uint16_t scannedFreqListLen,
139 bool scanRequestedByChre = true) {
140 chreWifiScanEvent event;
141 memset(&event, 0, sizeof(chreWifiScanEvent));
142 event.version = CHRE_WIFI_SCAN_EVENT_VERSION;
143 event.scanType = CHRE_WIFI_SCAN_TYPE_ACTIVE;
144 event.scannedFreqList = scannedFreqList;
145 event.scannedFreqListLen = scannedFreqListLen;
146 event.radioChainPref = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT;
147 gExpectedWifiScanEvent = event;
148
149 chreWifiScanCacheScanEventBegin(
150 static_cast<enum chreWifiScanType>(gExpectedWifiScanEvent->scanType),
151 gExpectedWifiScanEvent->ssidSetSize,
152 gExpectedWifiScanEvent->scannedFreqList,
153 gExpectedWifiScanEvent->scannedFreqListLen,
154 gExpectedWifiScanEvent->radioChainPref, scanRequestedByChre);
155 }
156
resultSpecifiedWifiCacheTest(size_t numEvents,InputVec & inputResults,ResultVec & expectedResults,const uint32_t * scannedFreqList,uint16_t scannedFreqListLen,bool scanRequestedByChre=true,bool scanMonitoringEnabled=false)157 void resultSpecifiedWifiCacheTest(size_t numEvents, InputVec &inputResults,
158 ResultVec &expectedResults,
159 const uint32_t *scannedFreqList,
160 uint16_t scannedFreqListLen,
161 bool scanRequestedByChre = true,
162 bool scanMonitoringEnabled = false) {
163 gWifiScanEventCompleted = false;
164 beginDefaultWifiCache(scannedFreqList, scannedFreqListLen,
165 scanRequestedByChre);
166
167 for (size_t i = 0; i < numEvents; i++) {
168 chreWifiScanCacheScanEventAdd(&inputResults[i]);
169 }
170
171 chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
172
173 if (scanRequestedByChre) {
174 EXPECT_TRUE(gWifiScanResponse.has_value());
175 EXPECT_EQ(gWifiScanResponse->pending, true);
176 ASSERT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_NONE);
177 } else {
178 EXPECT_FALSE(gWifiScanResponse.has_value());
179 }
180
181 size_t numEventsExpected = 0;
182 if (scanRequestedByChre || scanMonitoringEnabled) {
183 numEventsExpected = std::min(
184 numEvents, static_cast<size_t>(CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY));
185 ASSERT_TRUE(gWifiScanEventCompleted);
186 }
187
188 ASSERT_EQ(gWifiScanResultList.size(), numEventsExpected);
189 for (size_t i = 0; i < gWifiScanResultList.size(); i++) {
190 // ageMs is not known apriori
191 expectedResults[i].ageMs = gWifiScanResultList[i].ageMs;
192 EXPECT_EQ(memcmp(&gWifiScanResultList[i], &expectedResults[i],
193 sizeof(chreWifiScanResult)),
194 0);
195 }
196 }
197
cacheDefaultWifiCacheTest(size_t numEvents,const uint32_t * scannedFreqList,uint16_t scannedFreqListLen,bool scanRequestedByChre=true,bool scanMonitoringEnabled=false)198 void cacheDefaultWifiCacheTest(size_t numEvents,
199 const uint32_t *scannedFreqList,
200 uint16_t scannedFreqListLen,
201 bool scanRequestedByChre = true,
202 bool scanMonitoringEnabled = false) {
203 InputVec inputResults;
204 ResultVec expectedResults;
205
206 // Generate a default set of input and expected results if not specified
207 chreWifiScanResult result = {};
208 for (uint64_t i = 0; i < numEvents; i++) {
209 result.rssi = static_cast<int8_t>(i);
210 memcpy(result.bssid, &i, sizeof(result.bssid));
211 inputResults.push_back(result);
212
213 if (!expectedResults.full()) {
214 expectedResults.push_back(result);
215 } else {
216 int8_t minRssi = result.rssi;
217 int minIdx = -1;
218 for (uint64_t idx = 0; idx < expectedResults.size(); idx++) {
219 if (expectedResults[idx].rssi < minRssi) {
220 minRssi = expectedResults[idx].rssi;
221 minIdx = idx;
222 }
223 }
224 if (minIdx != -1) {
225 expectedResults[minIdx] = result;
226 }
227 }
228 }
229
230 resultSpecifiedWifiCacheTest(numEvents, inputResults, expectedResults,
231 scannedFreqList, scannedFreqListLen,
232 scanRequestedByChre, scanMonitoringEnabled);
233 }
234
testCacheDispatch(size_t numEvents,uint32_t maxScanAgeMs,bool expectSuccess)235 void testCacheDispatch(size_t numEvents, uint32_t maxScanAgeMs,
236 bool expectSuccess) {
237 cacheDefaultWifiCacheTest(numEvents, nullptr /* scannedFreqList */,
238 0 /* scannedFreqListLen */);
239
240 gExpectedWifiScanEvent->eventIndex = 0;
241 gWifiScanResponse.reset();
242 while (!gWifiScanResultList.empty()) {
243 gWifiScanResultList.pop_back();
244 }
245
246 struct chreWifiScanParams params = {
247 .scanType = CHRE_WIFI_SCAN_TYPE_NO_PREFERENCE,
248 .maxScanAgeMs = maxScanAgeMs,
249 .frequencyListLen = 0,
250 .frequencyList = nullptr,
251 .ssidListLen = 0,
252 .ssidList = nullptr,
253 .radioChainPref = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT,
254 .channelSet = CHRE_WIFI_CHANNEL_SET_NON_DFS,
255 };
256 EXPECT_EQ(chreWifiScanCacheDispatchFromCache(¶ms), expectSuccess);
257
258 EXPECT_EQ(gWifiScanResponse.has_value(), expectSuccess);
259 if (expectSuccess) {
260 EXPECT_TRUE(gWifiScanResponse->pending);
261 EXPECT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_NONE);
262 }
263
264 EXPECT_EQ(gWifiScanResultList.size(), expectSuccess ? numEvents : 0);
265 }
266
267 } // anonymous namespace
268
269 /************************************************
270 * Tests
271 ***********************************************/
TEST_F(WifiScanCacheTests,SingleWifiResultTest)272 TEST_F(WifiScanCacheTests, SingleWifiResultTest) {
273 cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
274 0 /* scannedFreqListLen */);
275 }
276
TEST_F(WifiScanCacheTests,MultiWifiResultTest)277 TEST_F(WifiScanCacheTests, MultiWifiResultTest) {
278 cacheDefaultWifiCacheTest(
279 CHRE_PAL_WIFI_SCAN_CACHE_MAX_RESULT_COUNT + 1 /* numEvents */,
280 nullptr /* scannedFreqList */, 0 /* scannedFreqListLen */);
281 }
282
TEST_F(WifiScanCacheTests,WifiResultOverflowTest)283 TEST_F(WifiScanCacheTests, WifiResultOverflowTest) {
284 cacheDefaultWifiCacheTest(
285 CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY + 42 /* numEvents */,
286 nullptr /* scannedFreqList */, 0 /* scannedFreqListLen */);
287 }
288
TEST_F(WifiScanCacheTests,WeakestRssiNotAddedToFullCacheTest)289 TEST_F(WifiScanCacheTests, WeakestRssiNotAddedToFullCacheTest) {
290 size_t numEvents = CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY + 1;
291 InputVec inputResults;
292 ResultVec expectedResults;
293
294 chreWifiScanResult result = {};
295 result.rssi = -20;
296 uint64_t i;
297 for (i = 0; i < CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY; i++) {
298 memcpy(result.bssid, &i, sizeof(result.bssid));
299 inputResults.push_back(result);
300 expectedResults.push_back(result);
301 }
302
303 result.rssi = -21;
304 memcpy(result.bssid, &i, sizeof(result.bssid));
305 inputResults.push_back(result);
306
307 resultSpecifiedWifiCacheTest(numEvents, inputResults, expectedResults,
308 nullptr /* scannedFreqList */,
309 0 /* scannedFreqListLen */);
310 }
311
TEST_F(WifiScanCacheTests,WeakestRssiReplacedAtEndOfFullCacheTest)312 TEST_F(WifiScanCacheTests, WeakestRssiReplacedAtEndOfFullCacheTest) {
313 size_t numEvents = CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY + 1;
314 InputVec inputResults;
315 ResultVec expectedResults;
316
317 chreWifiScanResult result = {};
318 result.rssi = -20;
319 uint64_t i;
320 for (i = 0; i < CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY - 1; i++) {
321 memcpy(result.bssid, &i, sizeof(result.bssid));
322 inputResults.push_back(result);
323 expectedResults.push_back(result);
324 }
325
326 result.rssi = -21;
327 memcpy(result.bssid, &i, sizeof(result.bssid));
328 i++;
329 inputResults.push_back(result);
330
331 result.rssi = -19;
332 memcpy(result.bssid, &i, sizeof(result.bssid));
333 i++;
334 inputResults.push_back(result);
335 expectedResults.push_back(result);
336
337 resultSpecifiedWifiCacheTest(numEvents, inputResults, expectedResults,
338 nullptr /* scannedFreqList */,
339 0 /* scannedFreqListLen */);
340 }
341
TEST_F(WifiScanCacheTests,EmptyWifiResultTest)342 TEST_F(WifiScanCacheTests, EmptyWifiResultTest) {
343 cacheDefaultWifiCacheTest(0 /* numEvents */, nullptr /* scannedFreqList */,
344 0 /* scannedFreqListLen */);
345 }
346
TEST_F(WifiScanCacheTests,FailedWifiCacheTest)347 TEST_F(WifiScanCacheTests, FailedWifiCacheTest) {
348 beginDefaultWifiCache(nullptr /* scannedFreqList */,
349 0 /* scannedFreqListLen */);
350
351 chreWifiScanCacheScanEventEnd(CHRE_ERROR);
352
353 EXPECT_TRUE(gWifiScanResponse.has_value());
354 EXPECT_FALSE(gWifiScanResponse->pending);
355 EXPECT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR);
356
357 EXPECT_EQ(gWifiScanResultList.size(), 0);
358 }
359
TEST_F(WifiScanCacheTests,FrequencyListTest)360 TEST_F(WifiScanCacheTests, FrequencyListTest) {
361 const uint32_t freqList[2] = {5210, 5240};
362 cacheDefaultWifiCacheTest(1 /* numEvents */, freqList, ARRAY_SIZE(freqList));
363 }
364
TEST_F(WifiScanCacheTests,InvalidFrequencyListTest)365 TEST_F(WifiScanCacheTests, InvalidFrequencyListTest) {
366 beginDefaultWifiCache(nullptr /* scannedFreqList */,
367 1 /* scannedFreqListLen */);
368
369 EXPECT_TRUE(gWifiScanResponse.has_value());
370 EXPECT_FALSE(gWifiScanResponse->pending);
371 EXPECT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_INVALID_ARGUMENT);
372
373 EXPECT_EQ(gWifiScanResultList.size(), 0);
374 }
375
TEST_F(WifiScanCacheTests,SequentialWifiResultTest)376 TEST_F(WifiScanCacheTests, SequentialWifiResultTest) {
377 cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
378 0 /* scannedFreqListLen */);
379
380 clearTestState();
381 cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
382 0 /* scannedFreqListLen */);
383 }
384
TEST_F(WifiScanCacheTests,ScanMonitorDisabledTest)385 TEST_F(WifiScanCacheTests, ScanMonitorDisabledTest) {
386 cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
387 0 /* scannedFreqListLen */,
388 false /* scanRequestedByChre */,
389 false /* scanMonitoringEnabled */);
390 }
391
TEST_F(WifiScanCacheTests,ScanMonitorEnabledTest)392 TEST_F(WifiScanCacheTests, ScanMonitorEnabledTest) {
393 chreWifiScanCacheConfigureScanMonitor(true /* enable */);
394 cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
395 0 /* scannedFreqListLen */,
396 false /* scanRequestedByChre */,
397 true /* scanMonitoringEnabled */);
398 }
399
TEST_F(WifiScanCacheTests,ScanMonitorEnableDisableTest)400 TEST_F(WifiScanCacheTests, ScanMonitorEnableDisableTest) {
401 chreWifiScanCacheConfigureScanMonitor(true /* enable */);
402 cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
403 0 /* scannedFreqListLen */,
404 false /* scanRequestedByChre */,
405 true /* scanMonitoringEnabled */);
406
407 clearTestState();
408 chreWifiScanCacheConfigureScanMonitor(false /* enable */);
409 cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
410 0 /* scannedFreqListLen */,
411 false /* scanRequestedByChre */,
412 false /* scanMonitoringEnabled */);
413 }
414
TEST_F(WifiScanCacheTests,CacheDispatchTest)415 TEST_F(WifiScanCacheTests, CacheDispatchTest) {
416 testCacheDispatch(1 /* numEvents */, 5000 /* maxScanAgeMs */,
417 true /* expectSuccess */);
418 }
419
TEST_F(WifiScanCacheTests,ZeroMaxScanAgeCacheDispatchTest)420 TEST_F(WifiScanCacheTests, ZeroMaxScanAgeCacheDispatchTest) {
421 testCacheDispatch(1 /* numEvents */, 0 /* maxScanAgeMs */,
422 false /* expectSuccess */);
423 }
424
TEST_F(WifiScanCacheTests,DuplicateScanResultTest)425 TEST_F(WifiScanCacheTests, DuplicateScanResultTest) {
426 beginDefaultWifiCache(nullptr /* scannedFreqList */,
427 0 /* scannedFreqListLen */,
428 true /* scanRequestedByChre */);
429
430 chreWifiScanResult result = {};
431 result.rssi = -98;
432 result.primaryChannel = 5270;
433 std::string sampleSsid = "Test ssid";
434 memcpy(result.ssid, sampleSsid.c_str(), sampleSsid.length());
435 result.ssidLen = sampleSsid.length();
436 std::string sampleBssid = "12:34:56:78:9a:bc";
437 memcpy(result.bssid, sampleBssid.c_str(), sampleBssid.length());
438 chreWifiScanResult result2 = {};
439 result2.rssi = -98;
440 result2.primaryChannel = 5270;
441 std::string sampleSsid2 = "Test ssid 2";
442 memcpy(result2.ssid, sampleSsid2.c_str(), sampleSsid2.length());
443 result2.ssidLen = sampleSsid2.length();
444 std::string sampleBssid2 = "34:56:78:9a:bc:de";
445 memcpy(result2.bssid, sampleBssid2.c_str(), sampleBssid2.length());
446
447 chreWifiScanCacheScanEventAdd(&result);
448 chreWifiScanCacheScanEventAdd(&result2);
449 chreWifiScanCacheScanEventAdd(&result);
450
451 chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
452
453 EXPECT_TRUE(gWifiScanResponse.has_value());
454 EXPECT_EQ(gWifiScanResponse->pending, true);
455 ASSERT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_NONE);
456
457 ASSERT_EQ(gWifiScanResultList.size(), 2);
458 result.ageMs = gWifiScanResultList[0].ageMs;
459 EXPECT_EQ(
460 memcmp(&gWifiScanResultList[0], &result, sizeof(chreWifiScanResult)), 0);
461 result2.ageMs = gWifiScanResultList[1].ageMs;
462 EXPECT_EQ(
463 memcmp(&gWifiScanResultList[1], &result2, sizeof(chreWifiScanResult)), 0);
464 }
465
TEST_F(WifiScanCacheTests,IncomingRequestDuringCachePopulationTest)466 TEST_F(WifiScanCacheTests, IncomingRequestDuringCachePopulationTest) {
467 beginDefaultWifiCache(nullptr /* scannedFreqList */,
468 0 /* scannedFreqListLen */,
469 false /* scanRequestedByChre */);
470
471 chreWifiScanResult result = {};
472 chreWifiScanCacheScanEventAdd(&result);
473
474 // An incoming request should upgrade the cache to a CHRE requested scan
475 // event.
476 chreWifiScanParams params = {
477 .scanType = CHRE_WIFI_SCAN_TYPE_ACTIVE,
478 .maxScanAgeMs = 5000,
479 .frequencyListLen = 0,
480 .frequencyList = nullptr,
481 .ssidListLen = 0,
482 .ssidList = nullptr,
483 .radioChainPref = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT,
484 .channelSet = CHRE_WIFI_CHANNEL_SET_NON_DFS,
485 };
486 EXPECT_TRUE(chreWifiScanCacheDispatchFromCache(¶ms));
487
488 // We shouldn't get the scan response until cache population is complete.
489 EXPECT_FALSE(gWifiScanResponse.has_value());
490
491 result.bssid[0] = 1;
492 chreWifiScanCacheScanEventAdd(&result);
493 chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
494
495 // CHRE should get the full cache result.
496 EXPECT_TRUE(gWifiScanResponse.has_value());
497 EXPECT_EQ(gWifiScanResponse->pending, true);
498 EXPECT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_NONE);
499 EXPECT_EQ(gWifiScanResultList.size(), 2);
500 }
501
TEST_F(WifiScanCacheTests,AgeCalculatedCorrectly)502 TEST_F(WifiScanCacheTests, AgeCalculatedCorrectly) {
503 constexpr auto kStartTime = Seconds(4);
504 overrideMonotonicTime(kStartTime);
505 beginDefaultWifiCache(nullptr /* scannedFreqList */,
506 0 /* scannedFreqListLen */);
507
508 overrideMonotonicTime(kStartTime + Milliseconds(100));
509 chreWifiScanResult result = {};
510 chreWifiScanCacheScanEventAdd(&result);
511
512 overrideMonotonicTime(kStartTime + Milliseconds(500));
513 chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
514
515 ASSERT_EQ(gWifiScanResultList.size(), 1);
516 EXPECT_EQ(gWifiScanResultList[0].ageMs, 500 - 100);
517 }
518
TEST_F(WifiScanCacheTests,AgeLongUptime)519 TEST_F(WifiScanCacheTests, AgeLongUptime) {
520 constexpr auto kStartTime = Seconds(60 * 60 * 24 * 50); // 50 days
521 overrideMonotonicTime(kStartTime);
522 beginDefaultWifiCache(nullptr /* scannedFreqList */,
523 0 /* scannedFreqListLen */);
524
525 overrideMonotonicTime(kStartTime + Milliseconds(500));
526 chreWifiScanResult result = {};
527 chreWifiScanCacheScanEventAdd(&result);
528
529 overrideMonotonicTime(kStartTime + Milliseconds(4000));
530 chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
531
532 ASSERT_EQ(gWifiScanResultList.size(), 1);
533 EXPECT_EQ(gWifiScanResultList[0].ageMs, 4000 - 500);
534 }
535
TEST_F(WifiScanCacheTests,AgeAvoidsUnderflow)536 TEST_F(WifiScanCacheTests, AgeAvoidsUnderflow) {
537 constexpr auto kStartTime = Seconds(30);
538 constexpr auto kEndTime = kStartTime + Seconds(5);
539 overrideMonotonicTime(kStartTime);
540 beginDefaultWifiCache(nullptr /* scannedFreqList */,
541 0 /* scannedFreqListLen */);
542
543 overrideMonotonicTime(Nanoseconds(0));
544 chreWifiScanResult result = {};
545 chreWifiScanCacheScanEventAdd(&result);
546
547 overrideMonotonicTime(kEndTime);
548 chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
549
550 ASSERT_EQ(gWifiScanResultList.size(), 1);
551 EXPECT_LT(gWifiScanResultList[0].ageMs,
552 Milliseconds(kEndTime - kStartTime).getMilliseconds());
553 }
554