13219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills /*
294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Copyright (C) 2016 The Android Open Source Project
394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills *
494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Licensed under the Apache License, Version 2.0 (the "License");
594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * you may not use this file except in compliance with the License.
694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * You may obtain a copy of the License at
794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills *
894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills *      http://www.apache.org/licenses/LICENSE-2.0
994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills *
1094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Unless required by applicable law or agreed to in writing, software
1194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * distributed under the License is distributed on an "AS IS" BASIS,
1294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * See the License for the specific language governing permissions and
14a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills * limitations under the License.
1594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills */
1694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
17a8367288377cbaed6371256ca837b7aa22280706Mitchell Willspackage com.android.server.wifi.scanner;
1894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
190ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Willsimport static com.android.server.wifi.ScanTestUtil.*;
2023216ca333dc411e6ce0829f777ca29992388443Roshan Piusimport static com.android.server.wifi.scanner.WifiScanningServiceImpl.WifiSingleScanStateMachine
2123216ca333dc411e6ce0829f777ca29992388443Roshan Pius        .CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS;
220ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills
230ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Willsimport static org.junit.Assert.*;
240ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Willsimport static org.mockito.Mockito.*;
2594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
26f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wileyimport android.app.test.MockAnswerUtil.AnswerWithArguments;
27107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhneimport android.app.test.TestAlarmManager;
2894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.content.BroadcastReceiver;
2994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.content.Context;
306c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silbersteinimport android.content.Intent;
3194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.content.IntentFilter;
32c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Piusimport android.net.wifi.ScanResult;
3394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.net.wifi.WifiManager;
3494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.net.wifi.WifiScanner;
351345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Willsimport android.os.Binder;
360ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Willsimport android.os.Bundle;
3794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.os.Handler;
3894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.os.Message;
391345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Willsimport android.os.RemoteException;
406c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silbersteinimport android.os.UserHandle;
410ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Willsimport android.os.WorkSource;
42f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wileyimport android.os.test.TestLooper;
4394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.test.suitebuilder.annotation.SmallTest;
44c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Piusimport android.util.Pair;
4594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
4694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport com.android.internal.app.IBatteryStats;
475382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Piusimport com.android.internal.util.AsyncChannel;
4894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport com.android.internal.util.Protocol;
49f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wileyimport com.android.internal.util.test.BidirectionalAsyncChannel;
50ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Piusimport com.android.server.wifi.Clock;
514fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Raoimport com.android.server.wifi.FakeWifiLog;
52e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Raoimport com.android.server.wifi.FrameworkFacade;
53a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.ScanResults;
54a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.TestUtil;
55a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiInjector;
56a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiMetrics;
57a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiNative;
58da94688198c864bb29be2e9603ebbe9ae6492a87Tamas Berghammerimport com.android.server.wifi.nano.WifiMetricsProto;
59e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Raoimport com.android.server.wifi.util.WifiAsyncChannel;
6094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
6194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.junit.After;
6294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.junit.Before;
6394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.junit.Test;
6494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.mockito.ArgumentCaptor;
65d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Willsimport org.mockito.InOrder;
6694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.mockito.Mock;
6794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.mockito.MockitoAnnotations;
684fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Raoimport org.mockito.Spy;
69160c5fd3f82eeed7271d0efc44b6a409c9176326Paul Duffinimport org.mockito.compat.CapturingMatcher;
7094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
71d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Willsimport java.io.FileDescriptor;
72d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Willsimport java.io.PrintWriter;
73d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Willsimport java.io.StringWriter;
74c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Piusimport java.util.ArrayList;
75c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Piusimport java.util.Arrays;
76c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Piusimport java.util.Collections;
77d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silbersteinimport java.util.List;
78d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Willsimport java.util.regex.Pattern;
79c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
8094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills/**
81a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills * Unit tests for {@link com.android.server.wifi.scanner.WifiScanningServiceImpl}.
8294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills */
8394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills@SmallTest
8494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willspublic class WifiScanningServiceTest {
8594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public static final String TAG = "WifiScanningServiceTest";
8694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
871b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    private static final int TEST_MAX_SCAN_BUCKETS_IN_CAPABILITIES = 8;
881b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius
8994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Mock Context mContext;
90f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley    TestAlarmManager mAlarmManager;
9194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Mock WifiScannerImpl mWifiScannerImpl;
9294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Mock WifiScannerImpl.WifiScannerImplFactory mWifiScannerImplFactory;
9394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Mock IBatteryStats mBatteryStats;
94c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    @Mock WifiInjector mWifiInjector;
95e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao    @Mock FrameworkFacade mFrameworkFacade;
96107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne    @Mock Clock mClock;
974fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Rao    @Spy FakeWifiLog mLog;
98c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    WifiMetrics mWifiMetrics;
99f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley    TestLooper mLooper;
10094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    WifiScanningServiceImpl mWifiScanningServiceImpl;
10194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
102c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
10394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Before
10494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void setUp() throws Exception {
10594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        MockitoAnnotations.initMocks(this);
10694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
107f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley        mAlarmManager = new TestAlarmManager();
1088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mContext.getSystemService(Context.ALARM_SERVICE))
1098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(mAlarmManager.getAlarmManager());
1108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
111e6d8fa5fb50afdfc04922f7f87c2cac08db5bbecMitchell Wills        ChannelHelper channelHelper = new PresetKnownBandsChannelHelper(
11294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                new int[]{2400, 2450},
11394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                new int[]{5150, 5175},
11494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                new int[]{5600, 5650, 5660});
11594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
116f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley        mLooper = new TestLooper();
11746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mWifiMetrics = new WifiMetrics(mClock, mLooper.getLooper());
118ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius        when(mWifiScannerImplFactory
119fee1cae825bad9459edcefb67fa600874d875816Ningyuan Wang                .create(any(), any(), any()))
12094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                .thenReturn(mWifiScannerImpl);
1217e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        when(mWifiScannerImpl.getChannelHelper()).thenReturn(channelHelper);
122c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
1234fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Rao        when(mWifiInjector.makeLog(anyString())).thenReturn(mLog);
124e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        WifiAsyncChannel mWifiAsyncChannel = new WifiAsyncChannel("ScanningServiceTest");
125e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiAsyncChannel.setWifiLog(mLog);
126e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        when(mFrameworkFacade.makeWifiAsyncChannel(anyString())).thenReturn(mWifiAsyncChannel);
127e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade);
12823216ca333dc411e6ce0829f777ca29992388443Roshan Pius        when(mWifiInjector.getClock()).thenReturn(mClock);
12994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mWifiScanningServiceImpl = new WifiScanningServiceImpl(mContext, mLooper.getLooper(),
130c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiScannerImplFactory, mBatteryStats, mWifiInjector);
13194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
13294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
13394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @After
13494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void cleanup() {
13594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        validateMockitoUsage();
13694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
13794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
138d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    /**
139d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills     * Internal BroadcastReceiver that WifiScanningServiceImpl uses to listen for broadcasts
140d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills     * this is initialized by calling startServiceAndLoadDriver
141d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills     */
142d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    BroadcastReceiver mBroadcastReceiver;
14394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
14494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    private WifiScanner.ScanSettings generateValidScanSettings() {
14594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        return createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
14694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
14794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
14894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
14994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    private BidirectionalAsyncChannel connectChannel(Handler handler) {
15094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        BidirectionalAsyncChannel controlChannel = new BidirectionalAsyncChannel();
15194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        controlChannel.connect(mLooper.getLooper(), mWifiScanningServiceImpl.getMessenger(),
15294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                handler);
15394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mLooper.dispatchAll();
15494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        controlChannel.assertConnected();
15594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        return controlChannel;
15694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
15794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
1585751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler) {
15994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
160d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        order.verify(handler).handleMessage(messageCaptor.capture());
16194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        return messageCaptor.getValue();
16294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
16394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
1645751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler,
1658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            final int what) {
1668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        CapturingMatcher<Message> messageMatcher = new CapturingMatcher<Message>() {
167160c5fd3f82eeed7271d0efc44b6a409c9176326Paul Duffin            public boolean matchesObject(Object argument) {
1688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                Message message = (Message) argument;
1698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                return message.what == what;
1708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            }
1718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        };
1728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        order.verify(handler).handleMessage(argThat(messageMatcher));
1738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        return messageMatcher.getLastValue();
1748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
1758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
176d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    private static void verifyScanResultsReceived(InOrder order, Handler handler, int listenerId,
177d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            WifiScanner.ScanData... expected) {
1788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler,
1798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                WifiScanner.CMD_SCAN_RESULT);
180d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertScanResultsMessage(listenerId, expected, scanResultMessage);
181d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
182d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
1835751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void assertScanResultsMessage(int listenerId, WifiScanner.ScanData[] expected,
184d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            Message scanResultMessage) {
185d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertEquals("what", WifiScanner.CMD_SCAN_RESULT, scanResultMessage.what);
186d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertEquals("listenerId", listenerId, scanResultMessage.arg2);
187d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertScanDatasEquals(expected,
188d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                ((WifiScanner.ParcelableScanData) scanResultMessage.obj).getResults());
189d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
190d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
191d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    private static void verifySingleScanCompletedReceived(InOrder order, Handler handler,
1925751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            int listenerId) {
1938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Message completedMessage = verifyHandleMessageAndGetMessage(order, handler,
1948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                WifiScanner.CMD_SINGLE_SCAN_COMPLETED);
1958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertSingleScanCompletedMessage(listenerId, completedMessage);
1968adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
1978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
1985751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void assertSingleScanCompletedMessage(int listenerId, Message completedMessage) {
1998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertEquals("what", WifiScanner.CMD_SINGLE_SCAN_COMPLETED, completedMessage.what);
2008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertEquals("listenerId", listenerId, completedMessage.arg2);
2018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
2028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
2035751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void sendBackgroundScanRequest(BidirectionalAsyncChannel controlChannel,
2040ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills            int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) {
2050ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        Bundle scanParams = new Bundle();
2060ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
2070ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        scanParams.putParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY, workSource);
208d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_BACKGROUND_SCAN, 0,
2090ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills                        scanRequestId, scanParams));
210d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
211d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
2125751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void sendSingleScanRequest(BidirectionalAsyncChannel controlChannel,
2130ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills            int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) {
2140ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        Bundle scanParams = new Bundle();
2150ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
2160ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        scanParams.putParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY, workSource);
2178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_SINGLE_SCAN, 0,
2180ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills                        scanRequestId, scanParams));
2198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
2208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
2211ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    private static void registerScanListener(BidirectionalAsyncChannel controlChannel,
2221ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int listenerRequestId) {
2231ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_REGISTER_SCAN_LISTENER, 0,
2241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        listenerRequestId, null));
2251ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
2261ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
2271ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    private static void deregisterScanListener(BidirectionalAsyncChannel controlChannel,
2281ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int listenerRequestId) {
2291ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_DEREGISTER_SCAN_LISTENER, 0,
2301ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        listenerRequestId, null));
2311ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
2321ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
2335751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void verifySuccessfulResponse(InOrder order, Handler handler, int arg2) {
234d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        Message response = verifyHandleMessageAndGetMessage(order, handler);
235d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertSuccessfulResponse(arg2, response);
23694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
23794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
2385751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void assertSuccessfulResponse(int arg2, Message response) {
239d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        if (response.what == WifiScanner.CMD_OP_FAILED) {
240d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj;
241d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            fail("response indicates failure, reason=" + result.reason
242d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                    + ", description=" + result.description);
243d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        } else {
244d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.what", WifiScanner.CMD_OP_SUCCEEDED, response.what);
245d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.arg2", arg2, response.arg2);
246d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        }
247d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
248d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
2495751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    /**
2505751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * If multiple results are expected for a single hardware scan then the order that they are
2515751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * dispatched is dependant on the order which they are iterated through internally. This
2521ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * function validates that the order is either one way or the other. A scan listener can
2531ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * optionally be provided as well and will be checked after the after the single scan requests.
2545751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     */
2555751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void verifyMultipleSingleScanResults(InOrder handlerOrder, Handler handler,
2561ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int requestId1, ScanResults results1, int requestId2, ScanResults results2,
2571ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int listenerRequestId, ScanResults listenerResults) {
2585751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
2591ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        handlerOrder.verify(handler, times(listenerResults == null ? 4 : 5))
2605751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                .handleMessage(messageCaptor.capture());
2615751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int firstListenerId = messageCaptor.getAllValues().get(0).arg2;
2625751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertTrue(firstListenerId + " was neither " + requestId2 + " nor " + requestId1,
2635751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                firstListenerId == requestId2 || firstListenerId == requestId1);
2645751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        if (firstListenerId == requestId2) {
2655751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertScanResultsMessage(requestId2,
2665751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    new WifiScanner.ScanData[] {results2.getScanData()},
2675751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    messageCaptor.getAllValues().get(0));
2685751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(1));
2695751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertScanResultsMessage(requestId1,
2705751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    new WifiScanner.ScanData[] {results1.getScanData()},
2715751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    messageCaptor.getAllValues().get(2));
2725751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertSingleScanCompletedMessage(requestId1, messageCaptor.getAllValues().get(3));
2731ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            if (listenerResults != null) {
2741ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                assertScanResultsMessage(listenerRequestId,
2751ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        new WifiScanner.ScanData[] {listenerResults.getScanData()},
2761ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        messageCaptor.getAllValues().get(4));
2771ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            }
2785751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        } else {
2795751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertScanResultsMessage(requestId1,
2805751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    new WifiScanner.ScanData[] {results1.getScanData()},
2815751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    messageCaptor.getAllValues().get(0));
2825751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertSingleScanCompletedMessage(requestId1, messageCaptor.getAllValues().get(1));
2835751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertScanResultsMessage(requestId2,
2845751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    new WifiScanner.ScanData[] {results2.getScanData()},
2855751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    messageCaptor.getAllValues().get(2));
2865751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(3));
2871ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            if (listenerResults != null) {
2881ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                assertScanResultsMessage(listenerRequestId,
2891ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        new WifiScanner.ScanData[] {listenerResults.getScanData()},
2901ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        messageCaptor.getAllValues().get(4));
2911ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            }
2925751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        }
2935751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    }
2945751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
2951ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    private static void verifyMultipleSingleScanResults(InOrder handlerOrder, Handler handler,
2961ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int requestId1, ScanResults results1, int requestId2, ScanResults results2) {
2971ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId2,
2981ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                results2, -1, null);
2991ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
3001ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
3015751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void verifyFailedResponse(InOrder order, Handler handler, int arg2,
30294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills            int expectedErrorReason, String expectedErrorDescription) {
303d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        Message response = verifyHandleMessageAndGetMessage(order, handler);
304d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertFailedResponse(arg2, expectedErrorReason, expectedErrorDescription, response);
30594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
30694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
3075751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void assertFailedResponse(int arg2, int expectedErrorReason,
30894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills            String expectedErrorDescription, Message response) {
309d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        if (response.what == WifiScanner.CMD_OP_SUCCEEDED) {
310d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            fail("response indicates success");
311d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        } else {
312d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.what", WifiScanner.CMD_OP_FAILED, response.what);
313d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.arg2", arg2, response.arg2);
314d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj;
315d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.obj.reason",
316d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                    expectedErrorReason, result.reason);
317d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.obj.description",
318d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                    expectedErrorDescription, result.description);
319d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        }
320d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
321d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
3228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    private WifiNative.ScanEventHandler verifyStartSingleScan(InOrder order,
3238adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            WifiNative.ScanSettings expected) {
3248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor =
3258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                ArgumentCaptor.forClass(WifiNative.ScanSettings.class);
3268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor =
3278adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class);
3288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        order.verify(mWifiScannerImpl).startSingleScan(scanSettingsCaptor.capture(),
3298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                scanEventHandlerCaptor.capture());
3308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue());
3318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        return scanEventHandlerCaptor.getValue();
3328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
3338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
334c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private WifiNative.ScanEventHandler verifyStartBackgroundScan(InOrder order,
335c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.ScanSettings expected) {
336d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor =
337d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                ArgumentCaptor.forClass(WifiNative.ScanSettings.class);
338c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor =
339c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class);
340d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        order.verify(mWifiScannerImpl).startBatchedScan(scanSettingsCaptor.capture(),
341c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                scanEventHandlerCaptor.capture());
342d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue());
343c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return scanEventHandlerCaptor.getValue();
34494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
34594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
3468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    private static final int MAX_AP_PER_SCAN = 16;
34794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    private void startServiceAndLoadDriver() {
34894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mWifiScanningServiceImpl.startService();
3491b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        setupAndLoadDriver(TEST_MAX_SCAN_BUCKETS_IN_CAPABILITIES);
3503040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    }
3513040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
3521b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    private void setupAndLoadDriver(int max_scan_buckets) {
35394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        when(mWifiScannerImpl.getScanCapabilities(any(WifiNative.ScanCapabilities.class)))
35494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                .thenAnswer(new AnswerWithArguments() {
35594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        public boolean answer(WifiNative.ScanCapabilities capabilities) {
35694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            capabilities.max_scan_cache_size = Integer.MAX_VALUE;
3571b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius                            capabilities.max_scan_buckets = max_scan_buckets;
3588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                            capabilities.max_ap_cache_per_scan = MAX_AP_PER_SCAN;
35994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            capabilities.max_rssi_sample_size = 8;
36094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            capabilities.max_scan_reporting_threshold = 10;
36194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            return true;
36294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        }
36394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                    });
364d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
365d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                ArgumentCaptor.forClass(BroadcastReceiver.class);
36694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        verify(mContext)
367d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                .registerReceiver(broadcastReceiverCaptor.capture(), any(IntentFilter.class));
368d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        mBroadcastReceiver = broadcastReceiverCaptor.getValue();
36968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        TestUtil.sendWifiScanAvailable(broadcastReceiverCaptor.getValue(), mContext,
37068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                WifiManager.WIFI_STATE_ENABLED);
37194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mLooper.dispatchAll();
37294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
37394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
374d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills    private String dumpService() {
375d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        StringWriter stringWriter = new StringWriter();
376d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        mWifiScanningServiceImpl.dump(new FileDescriptor(), new PrintWriter(stringWriter),
377d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills                new String[0]);
378d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        return stringWriter.toString();
379d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills    }
380d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills
381d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills    private void assertDumpContainsRequestLog(String type, int id) {
382d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        String serviceDump = dumpService();
3839e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills        Pattern logLineRegex = Pattern.compile("^.+" + type
3849e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills                + ": ClientInfo\\[uid=\\d+,android\\.os\\.Messenger@[a-f0-9]+\\],Id=" + id
3859e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills                + ".*$", Pattern.MULTILINE);
386d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        assertTrue("dump did not contain log with type=" + type + ", id=" + id +
38759298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                ": " + serviceDump + "\n",
38859298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                logLineRegex.matcher(serviceDump).find());
3893219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    }
39059298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills
39159298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills    private void assertDumpContainsCallbackLog(String callback, int id, String extra) {
39259298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        String serviceDump = dumpService();
39359298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        String extraPattern = extra == null ? "" : "," + extra;
3949e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills        Pattern logLineRegex = Pattern.compile("^.+" + callback
3959e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills                + ": ClientInfo\\[uid=\\d+,android\\.os\\.Messenger@[a-f0-9]+\\],Id=" + id
3969e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills                + extraPattern + "$", Pattern.MULTILINE);
39759298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertTrue("dump did not contain callback log with callback=" + callback + ", id=" + id +
39859298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                ", extra=" + extra + ": " + serviceDump + "\n",
399d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills                logLineRegex.matcher(serviceDump).find());
4003219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    }
401d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills
40294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Test
40394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void construct() throws Exception {
4048adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyNoMoreInteractions(mWifiScannerImpl, mWifiScannerImpl,
40594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                mWifiScannerImplFactory, mBatteryStats);
406d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        dumpService(); // make sure this succeeds
40794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
40894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
40994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Test
41094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void startService() throws Exception {
41194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mWifiScanningServiceImpl.startService();
412e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
41394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        verifyNoMoreInteractions(mWifiScannerImplFactory);
41494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
41594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        Handler handler = mock(Handler.class);
41694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
417d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        InOrder order = inOrder(handler);
4180ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendBackgroundScanRequest(controlChannel, 122, generateValidScanSettings(), null);
419d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        mLooper.dispatchAll();
420d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        verifyFailedResponse(order, handler, 122, WifiScanner.REASON_UNSPECIFIED, "not available");
42194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
42294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
42394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Test
4243040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    public void disconnectClientBeforeWifiEnabled() throws Exception {
4253040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mWifiScanningServiceImpl.startService();
426e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
4273040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class));
4283040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4293040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4303040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        controlChannel.disconnect();
4313040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4323040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    }
4333040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4343040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    @Test
43594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void loadDriver() throws Exception {
43694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        startServiceAndLoadDriver();
437e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
438ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius        verify(mWifiScannerImplFactory, times(1))
439fee1cae825bad9459edcefb67fa600874d875816Ningyuan Wang                .create(any(), any(), any());
44094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
44194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        Handler handler = mock(Handler.class);
44294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
443d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        InOrder order = inOrder(handler);
44494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
44594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
4460ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendBackgroundScanRequest(controlChannel, 192, generateValidScanSettings(), null);
447d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        mLooper.dispatchAll();
448d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        verifySuccessfulResponse(order, handler, 192);
449d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        assertDumpContainsRequestLog("addBackgroundScanRequest", 192);
45094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
45194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
45294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Test
4533040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    public void disconnectClientAfterStartingWifi() throws Exception {
4543040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mWifiScanningServiceImpl.startService();
455e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
4563040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class));
4573040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4583040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4591b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        setupAndLoadDriver(TEST_MAX_SCAN_BUCKETS_IN_CAPABILITIES);
4603040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4613040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        controlChannel.disconnect();
4623040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4633040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    }
4643040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4653040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    @Test
4663040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    public void connectAndDisconnectClientAfterStartingWifi() throws Exception {
4673040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        startServiceAndLoadDriver();
468e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
4693040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4703040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class));
4713040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4723040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        controlChannel.disconnect();
4733040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4743040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    }
4753040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4763040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    @Test
47794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void sendInvalidCommand() throws Exception {
47894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        startServiceAndLoadDriver();
479e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
48094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
48194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        Handler handler = mock(Handler.class);
48294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
483d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
484d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        controlChannel.sendMessage(Message.obtain(null, Protocol.BASE_WIFI_MANAGER));
485d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        mLooper.dispatchAll();
486d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        verifyFailedResponse(order, handler, 0, WifiScanner.REASON_INVALID_REQUEST,
487d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                "Invalid request");
48894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
4898adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
4901b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    @Test
4911b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    public void rejectBackgroundScanRequestWhenHalReturnsInvalidCapabilities() throws Exception {
4921b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        mWifiScanningServiceImpl.startService();
493e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
494e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao
4951b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        setupAndLoadDriver(0);
4961b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius
4971b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        Handler handler = mock(Handler.class);
4981b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
4991b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        InOrder order = inOrder(handler);
5001b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        sendBackgroundScanRequest(controlChannel, 122, generateValidScanSettings(), null);
5011b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        mLooper.dispatchAll();
5021b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        verifyFailedResponse(order, handler, 122, WifiScanner.REASON_UNSPECIFIED, "not available");
5031b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    }
5041b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius
5058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    private void doSuccessfulSingleScan(WifiScanner.ScanSettings requestSettings,
5061345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills            WifiNative.ScanSettings nativeSettings, ScanResults results) throws RemoteException {
5078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId = 12;
5081345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource = new WorkSource(2292);
5098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
510e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
5118adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
5138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
5148adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
5158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5168adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
5178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
5188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5191345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, workSource);
5208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
5228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings);
5238adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
5241345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource));
5258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
527f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                .thenReturn(results.getRawScanData());
5288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
5298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
531d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
532d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId);
53323216ca333dc411e6ce0829f777ca29992388443Roshan Pius        if (results.getScanData().isAllChannelsScanned()) {
53423216ca333dc411e6ce0829f777ca29992388443Roshan Pius            verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
53523216ca333dc411e6ce0829f777ca29992388443Roshan Pius        } else {
53623216ca333dc411e6ce0829f777ca29992388443Roshan Pius            verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
53723216ca333dc411e6ce0829f777ca29992388443Roshan Pius        }
5388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyNoMoreInteractions(handler);
5391345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource));
540d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId);
54159298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId,
542f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                "results=" + results.getScanData().getResults().length);
5438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
5448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5458adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
5468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a single scan for a band and verify that it is successful.
5478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
5488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
5498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanBandRequest() throws Exception {
5503219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
5513219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
5528adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
5533219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                ScanResults.create(0, true, 2400, 5150, 5175));
5548adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
5558adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
5578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a single scan for a list of channels and verify that it is successful.
5588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
5598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
5608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanChannelsRequest() throws Exception {
5613219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400, 5150, 5175),
5623219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
5638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
5648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                ScanResults.create(0, 2400, 5150, 5175));
5658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
5668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
5683219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills     * Do a single scan for a list of all channels and verify that it is successful.
5693219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills     */
5703219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    @Test
5713219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    public void sendSingleScanAllChannelsRequest() throws Exception {
5723219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(
5733219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                channelsToSpec(2400, 2450, 5150, 5175, 5600, 5650, 5660),
5743219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
5753219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
5763219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                ScanResults.create(0, true, 2400, 5150, 5175));
5773219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    }
5783219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills
5793219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    /**
580f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     * Do a single scan with no results and verify that it is successful.
581f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     */
582f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    @Test
583f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    public void sendSingleScanRequestWithNoResults() throws Exception {
584f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
585f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
586f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
587f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                ScanResults.create(0, new int[0]));
588f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    }
589f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills
590f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    /**
591f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     * Do a single scan with results that do not match the requested scan and verify that it is
592f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     * still successful (and returns no results).
593f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     */
594f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    @Test
595f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    public void sendSingleScanRequestWithBadRawResults() throws Exception {
596f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_24_GHZ, 0,
597f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
598f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        // Create a set of scan results that has results not matching the request settings, but is
599f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        // limited to zero results for the expected results.
600f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        ScanResults results = ScanResults.createOverflowing(0, 0,
601f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                ScanResults.generateNativeResults(0, 5150, 5171));
602f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
603f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                results);
604f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    }
605f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills
606f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    /**
6078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a single scan, which the hardware fails to start, and verify that a failure response is
6088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * delivered.
6098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
6108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
6118adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanRequestWhichFailsToStart() throws Exception {
6128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
6138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
6148adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId = 33;
6158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6168adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
617e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
6188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
6208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
6218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
6228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6238adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // scan fails
6248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
6258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(false);
6268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6270ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
6288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
6308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Scan is successfully queue, but then fails to execute
6318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
6328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        order.verify(handler, times(2)).handleMessage(messageCaptor.capture());
6338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertSuccessfulResponse(requestId, messageCaptor.getAllValues().get(0));
6348adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertFailedResponse(requestId, WifiScanner.REASON_UNSPECIFIED,
6358adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                "Failed to start single scan", messageCaptor.getAllValues().get(1));
6361345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verifyNoMoreInteractions(mBatteryStats);
637c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
638c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getOneshotScanCount(), 1);
639c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1);
640d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId);
6418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
6428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
6448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a single scan, which successfully starts, but fails partway through and verify that a
6458adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * failure response is delivered.
6468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
6478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
6488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanRequestWhichFailsAfterStart() throws Exception {
6498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
6508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
6518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId = 33;
6521345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource = new WorkSource(Binder.getCallingUid()); // don't explicitly set
6538adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6548adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
655e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
6568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
6588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
6598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
6608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // successful start
6628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
6638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
6648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6650ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
6668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Scan is successfully queue
6688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
6698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler =
6708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                verifyStartSingleScan(order, computeSingleScanNativeSettings(requestSettings));
6718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
6721345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource));
6738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // but then fails to execute
6758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_FAILED);
6768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
6778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyFailedResponse(order, handler, requestId,
6788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                WifiScanner.REASON_UNSPECIFIED, "Scan failed");
67956820e92fd4b1a0cee83f552905fc76fc8290146Mitchell Wills        assertDumpContainsCallbackLog("singleScanFailed", requestId,
68056820e92fd4b1a0cee83f552905fc76fc8290146Mitchell Wills                "reason=" + WifiScanner.REASON_UNSPECIFIED + ", Scan failed");
681c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getOneshotScanCount(), 1);
682c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1);
6831345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource));
6846c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
6858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
6868adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6871ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
6881ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Send a single scan request and then disable Wi-Fi before it completes
6891ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
6901ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
6911ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    public void sendSingleScanRequestThenDisableWifi() {
6921ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400), 0,
6931ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
6941ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId = 2293;
6951ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
6961ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
697e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
6981ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
6991ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
7001ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
7011ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7021ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
7031ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
7041ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
7051ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7061ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Run scan 1
7071ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
7081ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7091ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
7101ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7111ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // disable wifi
7121ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext,
7131ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                WifiManager.WIFI_STATE_DISABLED);
7141ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7151ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // validate failed response
7161ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7171ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyFailedResponse(order, handler, requestId, WifiScanner.REASON_UNSPECIFIED,
7181ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "Scan was interrupted");
7191ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyNoMoreInteractions(handler);
7201ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
7211ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7221ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
7231ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Send a single scan request, schedule a second pending scan and disable Wi-Fi before the first
7241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * scan completes.
7251ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
7261ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
7271ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    public void sendSingleScanAndPendingScanAndListenerThenDisableWifi() {
7281ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
7291ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
7301ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId1 = 2293;
7311ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7321ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450), 0,
7331ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
7341ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId2 = 2294;
7351ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7361ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int listenerRequestId = 2295;
7371ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7381ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
739e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
7401ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7411ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
7421ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
7431ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7441ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
7451ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
7461ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
7471ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7481ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Request scan 1
7491ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
7501ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7511ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId1);
7521ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7531ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Request scan 2
7541ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
7551ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7561ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId2);
7571ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7581ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Setup scan listener
7591ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        registerScanListener(controlChannel, listenerRequestId);
7601ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7611ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, listenerRequestId);
7621ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7631ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // disable wifi
7641ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext,
7651ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                WifiManager.WIFI_STATE_DISABLED);
7661ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7671ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // validate failed response
7681ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7691ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
7701ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        order.verify(handler, times(2)).handleMessage(messageCaptor.capture());
7711ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertFailedResponse(requestId1, WifiScanner.REASON_UNSPECIFIED,
7721ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "Scan was interrupted", messageCaptor.getAllValues().get(0));
7731ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertFailedResponse(requestId2, WifiScanner.REASON_UNSPECIFIED,
7741ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "Scan was interrupted", messageCaptor.getAllValues().get(1));
7751ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // No additional callbacks for scan listener
7761ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyNoMoreInteractions(handler);
7771ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
7788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
7808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Send a single scan request and then a second one after the first completes.
7818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
7828adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
7838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanRequestAfterPreviousCompletes() {
7848adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
7858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
7868adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId1 = 12;
78723216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults results1 = ScanResults.create(0, true, 2400);
7888adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7898adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7908adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
7918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
7928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId2 = 13;
79323216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults results2 = ScanResults.create(0, true, 2450);
7948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7968adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
797e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
7988adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
8008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
8018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
8038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
8046c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl, mContext);
8058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Run scan 1
8070ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
8088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(order,
8118adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings1));
8128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, requestId1);
8138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8148adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 1 results
8158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
8168adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results1.getScanData());
8178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
8188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8206c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // Note: The order of the following verification calls looks out of order if you compare to
8216c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // the source code of WifiScanningServiceImpl WifiSingleScanStateMachine.reportScanResults.
8226c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // This is due to the fact that verifyScanResultsReceived and
8236c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // verifySingleScanCompletedReceived require an additional call to handle the message that
8246c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // is created in reportScanResults.  This handling is done in the two verify*Received calls
8256c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // that is run AFTER the reportScanResults method in WifiScanningServiceImpl completes.
8266c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        order.verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
827d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId1, results1.getScanData());
828d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId1);
8298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Run scan 2
8310ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
8328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8348adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(order,
8358adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings2));
8368adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, requestId2);
8378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 2 results
8398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
8408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results2.getScanData());
8418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
8428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8446c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        order.verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
845d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId2, results2.getScanData());
846d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId2);
8478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
8488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
8505751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * Send a single scan request and then a second one not satisfied by the first before the first
8515751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * completes. Verify that both are scheduled and succeed.
8528adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
8538adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
8548adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanRequestWhilePreviousScanRunning() {
8558adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
8568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
8578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId1 = 12;
85823216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults results1 = ScanResults.create(0, true, 2400);
8598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
8618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
8628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId2 = 13;
86323216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults results2 = ScanResults.create(0, true, 2450);
8648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
867e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
8688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
8708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
8718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
8738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
8748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder handlerOrder = inOrder(handler);
8758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
8768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Run scan 1
8780ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
8798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
8828adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings1));
8838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
8848adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Queue scan 2 (will not run because previous is in progress)
8860ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
8878adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8888adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
8898adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8908adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 1 results
8918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
8928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results1.getScanData());
8938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
8948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
896d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId1, results1.getScanData());
897d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId1);
8986c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
8998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // now that the first scan completed we expect the second one to start
9018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder,
9028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings2));
9038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9048adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 2 results
9058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
9068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results2.getScanData());
9078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
9088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
910d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId2, results2.getScanData());
911d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId2);
9126c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext, times(2)).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
913c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getOneshotScanCount(), 2);
914c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 2);
9158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
9168adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
9195751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * Send a single scan request and then two more before the first completes. Neither are
9205751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * satisfied by the first scan. Verify that the first completes and the second two are merged.
9218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
9228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
9231345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills    public void sendMultipleSingleScanRequestWhilePreviousScanRunning() throws RemoteException {
9248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
9258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
9268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId1 = 12;
9271345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource1 = new WorkSource(1121);
92823216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults results1 = ScanResults.create(0, false, 2400);
9298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
9318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
9328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId2 = 13;
9331345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource2 = new WorkSource(Binder.getCallingUid()); // don't explicitly set
93423216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults results2 = ScanResults.create(0, false, 2450, 5175, 2450);
9358adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9368adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(5150), 0,
9378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
9388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId3 = 15;
9391345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource3 = new WorkSource(2292);
94023216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults results3 = ScanResults.create(0, false, 5150, 5150, 5150, 5150);
9418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanSettings nativeSettings2and3 = createSingleScanNativeSettingsForChannels(
9438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channelsToSpec(2450, 5175, 5150));
9448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ScanResults results2and3 = ScanResults.merge(results2, results3);
9451345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource2and3 = new WorkSource();
9461345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        workSource2and3.add(workSource2);
9471345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        workSource2and3.add(workSource3);
9488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
951e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
9528adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9538adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
9548adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
9558adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
9578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
9588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder handlerOrder = inOrder(handler);
9598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
9608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Run scan 1
9621345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, workSource1);
9638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
9658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
9668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings1));
9678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
9681345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource1));
9691345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills
9708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Queue scan 2 (will not run because previous is in progress)
9721345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        // uses uid of calling process
9730ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
9748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
9758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
9768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Queue scan 3 (will not run because previous is in progress)
9781345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        sendSingleScanRequest(controlChannel, requestId3, requestSettings3, workSource3);
9798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
9808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId3);
9818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9828adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 1 results
9838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
9848adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results1.getScanData());
9858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
9868adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9878adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
988d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId1, results1.getScanData());
989d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId1);
99023216ca333dc411e6ce0829f777ca29992388443Roshan Pius        verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
9911345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource1));
9921345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource2and3));
9938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // now that the first scan completed we expect the second and third ones to start
9958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler2and3 = verifyStartSingleScan(nativeOrder,
9968adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                nativeSettings2and3);
9978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9988adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 2 and 3 results
9998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
10008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results2and3.getScanData());
10018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
10028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
10038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
10048adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
10055751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId2, results2, requestId3,
10065751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                results3);
1007c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getOneshotScanCount(), 3);
1008c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 3);
100959298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills
10101345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource2and3));
10111345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills
101259298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId1);
101359298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId2);
101459298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId3);
101559298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId1,
101659298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                "results=" + results1.getRawScanResults().length);
101759298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId2,
101859298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                "results=" + results2.getRawScanResults().length);
101959298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId3,
102059298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                "results=" + results3.getRawScanResults().length);
10218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
10228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
10235751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10245751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    /**
10255751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * Send a single scan request and then a second one satisfied by the first before the first
10265751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * completes. Verify that only one scan is scheduled.
10275751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     */
10285751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    @Test
10295751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    public void sendSingleScanRequestWhilePreviousScanRunningAndMergeIntoFirstScan() {
10305751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Split by frequency to make it easier to determine which results each request is expecting
10315751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results24GHz = ScanResults.create(0, 2400, 2400, 2400, 2450);
10325751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results5GHz = ScanResults.create(0, 5150, 5150, 5175);
10335751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults resultsBoth = ScanResults.merge(results24GHz, results5GHz);
10345751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10355751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
10365751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
10375751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId1 = 12;
10385751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results1 = resultsBoth;
10395751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10405751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(WifiScanner.WIFI_BAND_24_GHZ, 0,
10415751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
10425751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId2 = 13;
10435751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results2 = results24GHz;
10445751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10455751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10465751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        startServiceAndLoadDriver();
1047e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
10485751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10495751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
10505751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
10515751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10525751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        Handler handler = mock(Handler.class);
10535751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
10545751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        InOrder handlerOrder = inOrder(handler);
10555751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
10565751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10575751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Run scan 1
10585751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
10595751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10605751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
10615751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(nativeOrder,
10625751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                computeSingleScanNativeSettings(requestSettings1));
10635751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
10645751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10655751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Queue scan 2 (will be folded into ongoing scan)
10665751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
10675751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
10685751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
10695751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10705751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // dispatch scan 1 results
10715751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
10725751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                .thenReturn(resultsBoth.getScanData());
10735751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
10745751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10755751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
10765751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId2,
10775751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                results2);
10785751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10795751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertEquals(mWifiMetrics.getOneshotScanCount(), 2);
10805751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 2);
10815751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    }
10825751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10835751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    /**
10845751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * Send a single scan request and then two more before the first completes, one of which is
10855751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * satisfied by the first scan. Verify that the first two complete together the second scan is
10865751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * just for the other scan.
10875751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     */
10885751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    @Test
10895751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    public void sendMultipleSingleScanRequestWhilePreviousScanRunningAndMergeOneIntoFirstScan()
10905751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills          throws RemoteException {
10915751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Split by frequency to make it easier to determine which results each request is expecting
10925751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results2400 = ScanResults.create(0, 2400, 2400, 2400);
10935751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results2450 = ScanResults.create(0, 2450);
10945751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results1and3 = ScanResults.merge(results2400, results2450);
10955751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10965751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400, 2450), 0,
10975751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
10985751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId1 = 12;
10995751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WorkSource workSource1 = new WorkSource(1121);
11005751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results1 = results1and3;
11015751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11025751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
11035751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
11045751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId2 = 13;
11055751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WorkSource workSource2 = new WorkSource(Binder.getCallingUid()); // don't explicitly set
11065751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450);
11075751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11085751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(2400), 0,
11095751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
11105751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId3 = 15;
11115751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WorkSource workSource3 = new WorkSource(2292);
11125751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results3 = results2400;
11135751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11145751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        startServiceAndLoadDriver();
1115e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
11165751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11175751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
11185751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
11195751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11205751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        Handler handler = mock(Handler.class);
11215751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
11225751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        InOrder handlerOrder = inOrder(handler);
11235751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
11245751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11255751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Run scan 1
11265751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, workSource1);
11275751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11285751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11295751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
11305751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                computeSingleScanNativeSettings(requestSettings1));
11315751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
11325751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource1));
11335751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11345751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11355751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Queue scan 2 (will not run because previous is in progress)
11365751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // uses uid of calling process
11375751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
11385751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11395751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
11405751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11415751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Queue scan 3 (will be merged into the active scan)
11425751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId3, requestSettings3, workSource3);
11435751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11445751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId3);
11455751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11465751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // dispatch scan 1 results
11475751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
11485751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                .thenReturn(results1and3.getScanData());
11495751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
11505751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11515751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11525751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId3,
11535751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                results3);
11545751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // only the requests know at the beginning of the scan get blamed
11555751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource1));
11565751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource2));
11575751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11585751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // now that the first scan completed we expect the second and third ones to start
11595751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder,
11605751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                computeSingleScanNativeSettings(requestSettings2));
11615751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11625751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // dispatch scan 2 and 3 results
11635751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
11645751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                .thenReturn(results2.getScanData());
11655751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
11665751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11675751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11685751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
1169d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId2, results2.getScanData());
1170d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId2);
117123216ca333dc411e6ce0829f777ca29992388443Roshan Pius        verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
11725751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertEquals(mWifiMetrics.getOneshotScanCount(), 3);
11735751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 3);
11745751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11755751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource2));
11765751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11775751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId1);
11785751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId2);
11795751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId3);
11805751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId1,
11815751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                "results=" + results1.getRawScanResults().length);
11825751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId2,
11835751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                "results=" + results2.getRawScanResults().length);
11845751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId3,
11855751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                "results=" + results3.getRawScanResults().length);
11865751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    }
11875751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11881ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
1189d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * Verify that WifiService provides a way to get the most recent SingleScan results.
1190d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1191d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
1192d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void retrieveSingleScanResults() throws Exception {
1193d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiScanner.ScanSettings requestSettings =
1194d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
1195d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                              0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1196d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175);
1197d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        doSuccessfulSingleScan(requestSettings,
1198d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               computeSingleScanNativeSettings(requestSettings),
1199d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               expectedResults);
1200d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1201d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1202d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1203d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1204d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1205d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1206d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1207d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1208d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1209d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1210d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), expectedResults.getRawScanResults().length);
1211a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein
1212a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein        // Make sure that we logged the scan results in the dump method.
1213a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein        String serviceDump = dumpService();
1214a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein        Pattern logLineRegex = Pattern.compile("Latest scan results:");
1215a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein        assertTrue("dump did not contain Latest scan results: " + serviceDump + "\n",
1216a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein                logLineRegex.matcher(serviceDump).find());
1217d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1218d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1219d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
1220d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * Verify that WifiService provides a way to get the most recent SingleScan results even when
1221d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * they are empty.
1222d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1223d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
1224d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void retrieveSingleScanResultsEmpty() throws Exception {
1225d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
1226d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1227d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
1228d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ScanResults.create(0, new int[0]));
1229d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1230d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1231d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1232d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1233d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1234d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1235d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1236d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1237d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1238d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1239d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1240d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1241d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), 0);
1242d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1243d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1244d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
1245d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * Verify that WifiService will return empty SingleScan results if a scan has not been
1246d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * performed.
1247d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1248d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
1249d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void retrieveSingleScanResultsBeforeAnySingleScans() throws Exception {
1250d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        startServiceAndLoadDriver();
1251e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
1252d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1253d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1254d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1255d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1256d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1257d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1258d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1259d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1260d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1261d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1262d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1263d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), 0);
1264d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1265d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1266d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
126723216ca333dc411e6ce0829f777ca29992388443Roshan Pius     * Verify that the newest full scan results are returned by WifiService.getSingleScanResults.
1268d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1269d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
127023216ca333dc411e6ce0829f777ca29992388443Roshan Pius    public void retrieveMostRecentFullSingleScanResults() throws Exception {
1271d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
1272d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1273d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175);
1274d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        doSuccessfulSingleScan(requestSettings,
1275d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               computeSingleScanNativeSettings(requestSettings),
1276d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               expectedResults);
1277d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1278d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1279d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1280d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1281d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1282d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1283d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1284d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1285d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1286d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1287d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1288d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1289d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), expectedResults.getRawScanResults().length);
1290d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1291d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // now update with a new scan that only has one result
1292d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        int secondScanRequestId = 35;
1293d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        ScanResults expectedSingleResult = ScanResults.create(0, true, 5150);
1294d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        sendSingleScanRequest(controlChannel, secondScanRequestId, requestSettings, null);
1295d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1296d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1297d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order,
1298d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                computeSingleScanNativeSettings(requestSettings));
1299d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySuccessfulResponse(order, handler, secondScanRequestId);
1300d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1301d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // dispatch scan 2 results
1302d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        when(mWifiScannerImpl.getLatestSingleScanResults())
1303d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                .thenReturn(expectedSingleResult.getScanData());
1304d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
1305d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1306d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1307d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, secondScanRequestId,
1308d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                expectedSingleResult.getScanData());
1309d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, secondScanRequestId);
1310d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1311d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1312d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1313d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1314d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response2 = verifyHandleMessageAndGetMessage(order, handler);
1315d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1316d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results2 = Arrays.asList(
1317d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response2.obj).getResults());
1318d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results2.size(), expectedSingleResult.getRawScanResults().length);
1319d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1320d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1321d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
132223216ca333dc411e6ce0829f777ca29992388443Roshan Pius     * Verify that the newest partial scan results are not returned by
132323216ca333dc411e6ce0829f777ca29992388443Roshan Pius     * WifiService.getSingleScanResults.
132423216ca333dc411e6ce0829f777ca29992388443Roshan Pius     */
132523216ca333dc411e6ce0829f777ca29992388443Roshan Pius    @Test
132623216ca333dc411e6ce0829f777ca29992388443Roshan Pius    public void doesNotRetrieveMostRecentPartialSingleScanResults() throws Exception {
132723216ca333dc411e6ce0829f777ca29992388443Roshan Pius        WifiScanner.ScanSettings fullRequestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
132823216ca333dc411e6ce0829f777ca29992388443Roshan Pius                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
132923216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults expectedFullResults = ScanResults.create(0, true, 2400, 5150, 5175);
133023216ca333dc411e6ce0829f777ca29992388443Roshan Pius        doSuccessfulSingleScan(fullRequestSettings,
133123216ca333dc411e6ce0829f777ca29992388443Roshan Pius                computeSingleScanNativeSettings(fullRequestSettings),
133223216ca333dc411e6ce0829f777ca29992388443Roshan Pius                expectedFullResults);
133323216ca333dc411e6ce0829f777ca29992388443Roshan Pius
133423216ca333dc411e6ce0829f777ca29992388443Roshan Pius        Handler handler = mock(Handler.class);
133523216ca333dc411e6ce0829f777ca29992388443Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
133623216ca333dc411e6ce0829f777ca29992388443Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
133723216ca333dc411e6ce0829f777ca29992388443Roshan Pius
133823216ca333dc411e6ce0829f777ca29992388443Roshan Pius        controlChannel.sendMessage(
133923216ca333dc411e6ce0829f777ca29992388443Roshan Pius                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
134023216ca333dc411e6ce0829f777ca29992388443Roshan Pius        mLooper.dispatchAll();
134123216ca333dc411e6ce0829f777ca29992388443Roshan Pius        Message response = verifyHandleMessageAndGetMessage(order, handler);
134223216ca333dc411e6ce0829f777ca29992388443Roshan Pius
134323216ca333dc411e6ce0829f777ca29992388443Roshan Pius        List<ScanResult> results = Arrays.asList(
134423216ca333dc411e6ce0829f777ca29992388443Roshan Pius                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
134523216ca333dc411e6ce0829f777ca29992388443Roshan Pius        assertEquals(results.size(), expectedFullResults.getRawScanResults().length);
134623216ca333dc411e6ce0829f777ca29992388443Roshan Pius
134723216ca333dc411e6ce0829f777ca29992388443Roshan Pius        // now update with a new scan that only has one result
134823216ca333dc411e6ce0829f777ca29992388443Roshan Pius        int secondScanRequestId = 35;
134923216ca333dc411e6ce0829f777ca29992388443Roshan Pius        WifiScanner.ScanSettings partialRequestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH,
135023216ca333dc411e6ce0829f777ca29992388443Roshan Pius                0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
135123216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults expectedPartialResults = ScanResults.create(0, false, 5150);
135223216ca333dc411e6ce0829f777ca29992388443Roshan Pius        sendSingleScanRequest(controlChannel, secondScanRequestId, partialRequestSettings, null);
135323216ca333dc411e6ce0829f777ca29992388443Roshan Pius
135423216ca333dc411e6ce0829f777ca29992388443Roshan Pius        mLooper.dispatchAll();
135523216ca333dc411e6ce0829f777ca29992388443Roshan Pius        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order,
135623216ca333dc411e6ce0829f777ca29992388443Roshan Pius                computeSingleScanNativeSettings(partialRequestSettings));
135723216ca333dc411e6ce0829f777ca29992388443Roshan Pius        verifySuccessfulResponse(order, handler, secondScanRequestId);
135823216ca333dc411e6ce0829f777ca29992388443Roshan Pius
135923216ca333dc411e6ce0829f777ca29992388443Roshan Pius        // dispatch scan 2 results
136023216ca333dc411e6ce0829f777ca29992388443Roshan Pius        when(mWifiScannerImpl.getLatestSingleScanResults())
136123216ca333dc411e6ce0829f777ca29992388443Roshan Pius                .thenReturn(expectedPartialResults.getScanData());
136223216ca333dc411e6ce0829f777ca29992388443Roshan Pius        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
136323216ca333dc411e6ce0829f777ca29992388443Roshan Pius
136423216ca333dc411e6ce0829f777ca29992388443Roshan Pius        mLooper.dispatchAll();
136523216ca333dc411e6ce0829f777ca29992388443Roshan Pius        verifyScanResultsReceived(order, handler, secondScanRequestId,
136623216ca333dc411e6ce0829f777ca29992388443Roshan Pius                expectedPartialResults.getScanData());
136723216ca333dc411e6ce0829f777ca29992388443Roshan Pius        verifySingleScanCompletedReceived(order, handler, secondScanRequestId);
136823216ca333dc411e6ce0829f777ca29992388443Roshan Pius
136923216ca333dc411e6ce0829f777ca29992388443Roshan Pius        controlChannel.sendMessage(
137023216ca333dc411e6ce0829f777ca29992388443Roshan Pius                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
137123216ca333dc411e6ce0829f777ca29992388443Roshan Pius        mLooper.dispatchAll();
137223216ca333dc411e6ce0829f777ca29992388443Roshan Pius        Message response2 = verifyHandleMessageAndGetMessage(order, handler);
137323216ca333dc411e6ce0829f777ca29992388443Roshan Pius
137423216ca333dc411e6ce0829f777ca29992388443Roshan Pius        List<ScanResult> results2 = Arrays.asList(
137523216ca333dc411e6ce0829f777ca29992388443Roshan Pius                ((WifiScanner.ParcelableScanResults) response2.obj).getResults());
137623216ca333dc411e6ce0829f777ca29992388443Roshan Pius        assertEquals(results2.size(), expectedFullResults.getRawScanResults().length);
137723216ca333dc411e6ce0829f777ca29992388443Roshan Pius    }
137823216ca333dc411e6ce0829f777ca29992388443Roshan Pius
137923216ca333dc411e6ce0829f777ca29992388443Roshan Pius    /**
138023216ca333dc411e6ce0829f777ca29992388443Roshan Pius     * Verify that the scan results returned by WifiService.getSingleScanResults are not older
138123216ca333dc411e6ce0829f777ca29992388443Roshan Pius     * than {@link com.android.server.wifi.scanner.WifiScanningServiceImpl
138223216ca333dc411e6ce0829f777ca29992388443Roshan Pius     * .WifiSingleScanStateMachine#CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS}.
138323216ca333dc411e6ce0829f777ca29992388443Roshan Pius     */
138423216ca333dc411e6ce0829f777ca29992388443Roshan Pius    @Test
138523216ca333dc411e6ce0829f777ca29992388443Roshan Pius    public void doesNotRetrieveStaleScanResultsFromLastFullSingleScan() throws Exception {
138623216ca333dc411e6ce0829f777ca29992388443Roshan Pius        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
138723216ca333dc411e6ce0829f777ca29992388443Roshan Pius                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
138823216ca333dc411e6ce0829f777ca29992388443Roshan Pius        ScanResults scanResults = ScanResults.create(0, true, 2400, 5150, 5175);
138923216ca333dc411e6ce0829f777ca29992388443Roshan Pius
139023216ca333dc411e6ce0829f777ca29992388443Roshan Pius        // Out of the 3 scan results, modify the timestamp of 2 of them to be within the expiration
139123216ca333dc411e6ce0829f777ca29992388443Roshan Pius        // age and 1 out of it.
139223216ca333dc411e6ce0829f777ca29992388443Roshan Pius        long currentTimeInMillis = CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS * 2;
139323216ca333dc411e6ce0829f777ca29992388443Roshan Pius        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeInMillis);
139423216ca333dc411e6ce0829f777ca29992388443Roshan Pius        scanResults.getRawScanResults()[0].timestamp = (currentTimeInMillis - 1) * 1000;
139523216ca333dc411e6ce0829f777ca29992388443Roshan Pius        scanResults.getRawScanResults()[1].timestamp = (currentTimeInMillis - 2) * 1000;
139623216ca333dc411e6ce0829f777ca29992388443Roshan Pius        scanResults.getRawScanResults()[2].timestamp =
139723216ca333dc411e6ce0829f777ca29992388443Roshan Pius                (currentTimeInMillis - CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS) * 1000;
139823216ca333dc411e6ce0829f777ca29992388443Roshan Pius        List<ScanResult> expectedResults = new ArrayList<ScanResult>() {{
139923216ca333dc411e6ce0829f777ca29992388443Roshan Pius                add(scanResults.getRawScanResults()[0]);
140023216ca333dc411e6ce0829f777ca29992388443Roshan Pius                add(scanResults.getRawScanResults()[1]);
140123216ca333dc411e6ce0829f777ca29992388443Roshan Pius            }};
140223216ca333dc411e6ce0829f777ca29992388443Roshan Pius
140323216ca333dc411e6ce0829f777ca29992388443Roshan Pius        doSuccessfulSingleScan(requestSettings,
140423216ca333dc411e6ce0829f777ca29992388443Roshan Pius                computeSingleScanNativeSettings(requestSettings), scanResults);
140523216ca333dc411e6ce0829f777ca29992388443Roshan Pius
140623216ca333dc411e6ce0829f777ca29992388443Roshan Pius        Handler handler = mock(Handler.class);
140723216ca333dc411e6ce0829f777ca29992388443Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
140823216ca333dc411e6ce0829f777ca29992388443Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
140923216ca333dc411e6ce0829f777ca29992388443Roshan Pius
141023216ca333dc411e6ce0829f777ca29992388443Roshan Pius        controlChannel.sendMessage(
141123216ca333dc411e6ce0829f777ca29992388443Roshan Pius                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
141223216ca333dc411e6ce0829f777ca29992388443Roshan Pius        mLooper.dispatchAll();
141323216ca333dc411e6ce0829f777ca29992388443Roshan Pius        Message response = verifyHandleMessageAndGetMessage(order, handler);
141423216ca333dc411e6ce0829f777ca29992388443Roshan Pius
141523216ca333dc411e6ce0829f777ca29992388443Roshan Pius        List<ScanResult> results = Arrays.asList(
141623216ca333dc411e6ce0829f777ca29992388443Roshan Pius                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
141723216ca333dc411e6ce0829f777ca29992388443Roshan Pius        assertScanResultsEquals(expectedResults.toArray(new ScanResult[expectedResults.size()]),
141823216ca333dc411e6ce0829f777ca29992388443Roshan Pius                results.toArray(new ScanResult[results.size()]));
141923216ca333dc411e6ce0829f777ca29992388443Roshan Pius    }
142023216ca333dc411e6ce0829f777ca29992388443Roshan Pius
142123216ca333dc411e6ce0829f777ca29992388443Roshan Pius    /**
1422d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * Cached scan results should be cleared after the driver is unloaded.
1423d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1424d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
1425d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void validateScanResultsClearedAfterDriverUnloaded() throws Exception {
1426d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiScanner.ScanSettings requestSettings =
1427d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
1428d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                              0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1429d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175);
1430d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        doSuccessfulSingleScan(requestSettings,
1431d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               computeSingleScanNativeSettings(requestSettings),
1432d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               expectedResults);
1433d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1434d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1435d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1436d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1437d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1438d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1439d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1440d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1441d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1442d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1443d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), expectedResults.getRawScanResults().length);
1444d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1445d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // disable wifi
1446d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        TestUtil.sendWifiScanAvailable(mBroadcastReceiver,
1447d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                                       mContext,
1448d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                                       WifiManager.WIFI_STATE_DISABLED);
1449d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // Now get scan results again. The returned list should be empty since we
1450d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // clear the cache when exiting the DriverLoaded state.
1451d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1452d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1453d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1454d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response2 = verifyHandleMessageAndGetMessage(order, handler);
1455d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results2 = Arrays.asList(
1456d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response2.obj).getResults());
1457d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results2.size(), 0);
1458d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1459d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1460d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
14611ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Register a single scan listener and do a single scan
14621ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
14631ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
14641ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    public void registerScanListener() throws Exception {
14651ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
14661ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
14671ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanSettings nativeSettings = computeSingleScanNativeSettings(requestSettings);
14681ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results = ScanResults.create(0, 2400, 5150, 5175);
14691ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14701ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId = 12;
14711ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int listenerRequestId = 13;
14721ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14731ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
1474e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
14751ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14761ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
14771ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
14781ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
14791ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14801ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
14811ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
14821ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14831ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        registerScanListener(controlChannel, listenerRequestId);
14841ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
14851ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, listenerRequestId);
14861ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14871ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
14881ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14891ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
14901ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings);
14911ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
14921ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14931ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
14941ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                .thenReturn(results.getRawScanData());
14951ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
14961ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14971ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
1498d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
1499d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId);
1500d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, listenerRequestId, results.getScanData());
150123216ca333dc411e6ce0829f777ca29992388443Roshan Pius        verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
15021ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyNoMoreInteractions(handler);
15031ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15041ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsRequestLog("registerScanListener", listenerRequestId);
15051ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsCallbackLog("singleScanResults", listenerRequestId,
15061ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "results=" + results.getScanData().getResults().length);
15071ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
15081ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15091ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
15101ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Register a single scan listener and do a single scan
15111ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
15121ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
15131ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    public void deregisterScanListener() throws Exception {
15141ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
15151ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
15161ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanSettings nativeSettings = computeSingleScanNativeSettings(requestSettings);
15171ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results = ScanResults.create(0, 2400, 5150, 5175);
15181ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15191ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId = 12;
15201ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int listenerRequestId = 13;
15211ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15221ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
1523e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
15241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15251ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
15261ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
15271ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
15281ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15291ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
15301ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
15311ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15321ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        registerScanListener(controlChannel, listenerRequestId);
15331ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
15341ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, listenerRequestId);
15351ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15361ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
15371ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15381ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
15391ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings);
15401ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
15411ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15421ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        deregisterScanListener(controlChannel, listenerRequestId);
15431ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
15441ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15451ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
15461ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                .thenReturn(results.getRawScanData());
15471ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
15481ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15491ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
1550d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
1551d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId);
155223216ca333dc411e6ce0829f777ca29992388443Roshan Pius        verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
15531ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyNoMoreInteractions(handler);
15541ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15551ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsRequestLog("registerScanListener", listenerRequestId);
15561ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsRequestLog("deregisterScanListener", listenerRequestId);
15571ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
15581ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15591ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
15601ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Send a single scan request and then two more before the first completes. Neither are
15611ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * satisfied by the first scan. Verify that the first completes and the second two are merged.
15621ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
15631ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
1564d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void scanListenerReceivesAllResults() throws RemoteException {
15651ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
15661ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
15671ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId1 = 12;
15681ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results1 = ScanResults.create(0, 2400);
15691ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15701ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
15711ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
15721ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId2 = 13;
15731ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450);
15741ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15751ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(5150), 0,
15761ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
15771ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId3 = 15;
15781ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results3 = ScanResults.create(0, 5150, 5150, 5150, 5150);
15791ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15801ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanSettings nativeSettings2and3 = createSingleScanNativeSettingsForChannels(
15811ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channelsToSpec(2450, 5175, 5150));
15821ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results2and3 = ScanResults.merge(results2, results3);
15831ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15841ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int listenerRequestId = 13;
15851ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15861ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15871ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
1588e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
15891ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15901ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
15911ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
15921ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15931ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
15941ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
15951ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder handlerOrder = inOrder(handler);
15961ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
15971ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15981ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Run scan 1
15991ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
16001ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16011ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
16021ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
16031ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                computeSingleScanNativeSettings(requestSettings1));
16041ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
16051ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16061ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16071ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Queue scan 2 (will not run because previous is in progress)
16081ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
16091ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
16101ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
16111ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16121ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Queue scan 3 (will not run because previous is in progress)
16131ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId3, requestSettings3, null);
16141ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
16151ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId3);
16161ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16171ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Register scan listener
16181ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        registerScanListener(controlChannel, listenerRequestId);
16191ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
16201ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, listenerRequestId);
16211ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16221ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // dispatch scan 1 results
16231ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
16241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                .thenReturn(results1.getScanData());
16251ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
16261ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16271ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
1628d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId1, results1.getScanData());
1629d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId1);
1630d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, listenerRequestId, results1.getScanData());
163123216ca333dc411e6ce0829f777ca29992388443Roshan Pius        verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
16321ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16331ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // now that the first scan completed we expect the second and third ones to start
16341ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanEventHandler eventHandler2and3 = verifyStartSingleScan(nativeOrder,
16351ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                nativeSettings2and3);
16361ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16371ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // dispatch scan 2 and 3 results
16381ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
16391ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                .thenReturn(results2and3.getScanData());
16401ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
16411ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16421ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
16431ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16441ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId2, results2, requestId3,
16451ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                results3, listenerRequestId, results2and3);
16461ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16471ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsRequestLog("registerScanListener", listenerRequestId);
16481ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsCallbackLog("singleScanResults", listenerRequestId,
16491ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "results=" + results1.getRawScanResults().length);
16501ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsCallbackLog("singleScanResults", listenerRequestId,
16511ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "results=" + results2and3.getRawScanResults().length);
16521ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
16531ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16541ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
16558adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    private void doSuccessfulBackgroundScan(WifiScanner.ScanSettings requestSettings,
16568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            WifiNative.ScanSettings nativeSettings) {
16578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
1658e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
16598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
16608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
16618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
16628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
16638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
16648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
16658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
16668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
16670ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendBackgroundScanRequest(controlChannel, 12, requestSettings, null);
16688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
16698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyStartBackgroundScan(order, nativeSettings);
16708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, 12);
16718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyNoMoreInteractions(handler);
167259298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsRequestLog("addBackgroundScanRequest", 12);
16738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
16748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
16758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
16768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a background scan for a band and verify that it is successful.
16778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
16788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
16798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendBackgroundScanBandRequest() throws Exception {
1680e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 30000,
16818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
16828adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder()
1683e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .withBasePeriod(30000)
16848adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withMaxApPerScan(MAX_AP_PER_SCAN)
168595984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills                .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH)
1686e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .addBucketWithBand(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
16878adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        WifiScanner.WIFI_BAND_BOTH)
16888adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .build();
16898adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        doSuccessfulBackgroundScan(requestSettings, nativeSettings);
1690c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getBackgroundScanCount(), 1);
16918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
16928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
16938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
16948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a background scan for a list of channels and verify that it is successful.
16958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
16968adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
16978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendBackgroundScanChannelsRequest() throws Exception {
1698e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(5150), 30000,
16998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
17008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder()
1701e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .withBasePeriod(30000)
17028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withMaxApPerScan(MAX_AP_PER_SCAN)
170395984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills                .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH)
1704e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .addBucketWithChannels(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5150)
17058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .build();
17068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        doSuccessfulBackgroundScan(requestSettings, nativeSettings);
17078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
1708c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1709c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> createScanSettingsForHwPno()
1710c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            throws Exception {
1711c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiScanner.ScanSettings requestSettings = createRequest(
1712e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                channelsToSpec(0, 2400, 5150, 5175), 30000, 0, 20,
1713c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1714c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder()
1715e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .withBasePeriod(30000)
1716c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                .withMaxApPerScan(MAX_AP_PER_SCAN)
1717c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH)
1718e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .addBucketWithChannels(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
1719c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                        0, 2400, 5150, 5175)
1720c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                .build();
1721c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return Pair.create(requestSettings, nativeSettings);
1722c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1723c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1724c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> createScanSettingsForSwPno()
1725c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            throws Exception {
1726c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> settingsPair =
1727c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForHwPno();
1728c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1729c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiScanner.ScanSettings requestSettings = settingsPair.first;
1730c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.ScanSettings nativeSettings = settingsPair.second;
1731c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        // reportEvents field is overridden for SW PNO
1732c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        for (int i = 0; i < nativeSettings.buckets.length; i++) {
1733c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativeSettings.buckets[i].report_events = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
1734c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                    | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT;
1735c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        }
1736c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return Pair.create(requestSettings, nativeSettings);
1737c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1738c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1739c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> createPnoSettings(
1740c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            ScanResults results)
1741c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            throws Exception {
1742c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiScanner.PnoSettings requestPnoSettings = new WifiScanner.PnoSettings();
1743c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        requestPnoSettings.networkList =
1744c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                new WifiScanner.PnoSettings.PnoNetwork[results.getRawScanResults().length];
1745c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int i = 0;
1746c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        for (ScanResult scanResult : results.getRawScanResults()) {
1747c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            requestPnoSettings.networkList[i++] =
1748c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                    new WifiScanner.PnoSettings.PnoNetwork(scanResult.SSID);
1749c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        }
1750c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1751c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.PnoSettings nativePnoSettings = new WifiNative.PnoSettings();
1752c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.min5GHzRssi = requestPnoSettings.min5GHzRssi;
1753c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.min24GHzRssi = requestPnoSettings.min24GHzRssi;
1754c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.initialScoreMax = requestPnoSettings.initialScoreMax;
1755c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.currentConnectionBonus = requestPnoSettings.currentConnectionBonus;
1756c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.sameNetworkBonus = requestPnoSettings.sameNetworkBonus;
1757c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.secureBonus = requestPnoSettings.secureBonus;
1758c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.band5GHzBonus = requestPnoSettings.band5GHzBonus;
1759c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.isConnected = requestPnoSettings.isConnected;
1760c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.networkList =
1761c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                new WifiNative.PnoNetwork[requestPnoSettings.networkList.length];
1762c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        for (i = 0; i < requestPnoSettings.networkList.length; i++) {
1763c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativePnoSettings.networkList[i] = new WifiNative.PnoNetwork();
1764c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativePnoSettings.networkList[i].ssid = requestPnoSettings.networkList[i].ssid;
1765c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativePnoSettings.networkList[i].flags = requestPnoSettings.networkList[i].flags;
1766c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativePnoSettings.networkList[i].auth_bit_field =
1767c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                    requestPnoSettings.networkList[i].authBitField;
1768c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        }
1769c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return Pair.create(requestPnoSettings, nativePnoSettings);
1770c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1771c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1772c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private ScanResults createScanResultsForPno() {
1773c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return ScanResults.create(0, 2400, 5150, 5175);
1774c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1775c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1776c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private ScanResults createScanResultsForPnoWithNoIE() {
1777c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return ScanResults.createWithNoIE(0, 2400, 5150, 5175);
1778c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1779c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1780c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private WifiNative.PnoEventHandler verifyHwPno(InOrder order,
1781c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.PnoSettings expected) {
1782c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ArgumentCaptor<WifiNative.PnoSettings> pnoSettingsCaptor =
1783c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                ArgumentCaptor.forClass(WifiNative.PnoSettings.class);
1784c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ArgumentCaptor<WifiNative.PnoEventHandler> pnoEventHandlerCaptor =
1785c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                ArgumentCaptor.forClass(WifiNative.PnoEventHandler.class);
1786c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        order.verify(mWifiScannerImpl).setHwPnoList(pnoSettingsCaptor.capture(),
1787c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                pnoEventHandlerCaptor.capture());
1788c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        assertNativePnoSettingsEquals(expected, pnoSettingsCaptor.getValue());
1789c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return pnoEventHandlerCaptor.getValue();
1790c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1791c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1792c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void sendPnoScanRequest(BidirectionalAsyncChannel controlChannel,
1793c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            int scanRequestId, WifiScanner.ScanSettings scanSettings,
1794c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiScanner.PnoSettings pnoSettings) {
1795c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Bundle pnoParams = new Bundle();
1796c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        scanSettings.isPnoScan = true;
1797c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        pnoParams.putParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY, scanSettings);
1798c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        pnoParams.putParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY, pnoSettings);
1799c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_PNO_SCAN, 0,
1800c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                scanRequestId, pnoParams));
1801c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1802c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1803c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void assertPnoNetworkFoundMessage(int listenerId, ScanResult[] expected,
1804c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            Message networkFoundMessage) {
1805c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        assertEquals("what", WifiScanner.CMD_PNO_NETWORK_FOUND, networkFoundMessage.what);
1806c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        assertEquals("listenerId", listenerId, networkFoundMessage.arg2);
1807a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills        assertScanResultsEquals(expected,
1808c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                ((WifiScanner.ParcelableScanResults) networkFoundMessage.obj).getResults());
1809c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1810c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1811d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    private void verifyPnoNetworkFoundReceived(InOrder order, Handler handler, int listenerId,
1812c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            ScanResult[] expected) {
1813c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler,
1814c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                WifiScanner.CMD_PNO_NETWORK_FOUND);
1815c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        assertPnoNetworkFoundMessage(listenerId, expected, scanResultMessage);
1816c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1817c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1818c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectSuccessfulBackgroundScan(InOrder order,
1819c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.ScanSettings nativeSettings, ScanResults results) {
1820c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
1821c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.ScanEventHandler.class))).thenReturn(true);
1822c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1823c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.ScanEventHandler eventHandler = verifyStartBackgroundScan(order, nativeSettings);
1824c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiScanner.ScanData[] scanDatas = new WifiScanner.ScanData[1];
1825c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        scanDatas[0] = results.getScanData();
1826c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        for (ScanResult fullScanResult : results.getRawScanResults()) {
1827c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            eventHandler.onFullScanResult(fullScanResult, 0);
1828c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        }
1829c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.getLatestBatchedScanResults(anyBoolean())).thenReturn(scanDatas);
1830c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
1831c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1832c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1833c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1834c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectHwPnoScanWithNoBackgroundScan(InOrder order, Handler handler, int requestId,
1835c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.PnoSettings nativeSettings, ScanResults results) {
1836c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(true);
1837c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(false);
1838c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1839c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.setHwPnoList(any(WifiNative.PnoSettings.class),
1840c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.PnoEventHandler.class))).thenReturn(true);
1841c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1842c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.PnoEventHandler eventHandler = verifyHwPno(order, nativeSettings);
1843c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        verifySuccessfulResponse(order, handler, requestId);
1844c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        eventHandler.onPnoNetworkFound(results.getRawScanResults());
1845c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1846c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1847c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1848c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectHwPnoScanWithBackgroundScan(InOrder order, Handler handler, int requestId,
1849c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.ScanSettings nativeScanSettings,
1850c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.PnoSettings nativePnoSettings, ScanResults results) {
1851c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(true);
1852c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(true);
1853c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1854c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.setHwPnoList(any(WifiNative.PnoSettings.class),
1855c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.PnoEventHandler.class))).thenReturn(true);
1856c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
1857c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.ScanEventHandler.class))).thenReturn(true);
1858c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1859c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.PnoEventHandler eventHandler = verifyHwPno(order, nativePnoSettings);
1860c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        verifySuccessfulResponse(order, handler, requestId);
1861c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        verifyStartBackgroundScan(order, nativeScanSettings);
1862c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        eventHandler.onPnoNetworkFound(results.getRawScanResults());
1863c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1864c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1865c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1866c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectHwPnoScanWithBackgroundScanWithNoIE(InOrder order, Handler handler,
1867c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            int requestId, WifiNative.ScanSettings nativeBackgroundScanSettings,
1868c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.ScanSettings nativeSingleScanSettings,
1869c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.PnoSettings nativePnoSettings, ScanResults results) {
1870c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
1871c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.ScanEventHandler.class))).thenReturn(true);
1872c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1873c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectHwPnoScanWithBackgroundScan(order, handler, requestId, nativeBackgroundScanSettings,
1874c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                nativePnoSettings, results);
1875c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.ScanEventHandler eventHandler =
1876c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                verifyStartSingleScan(order, nativeSingleScanSettings);
1877c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.getLatestSingleScanResults()).thenReturn(results.getScanData());
1878c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
1879c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1880c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1881c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectSwPnoScan(InOrder order, WifiNative.ScanSettings nativeScanSettings,
1882c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            ScanResults results) {
1883c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(false);
1884c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(true);
1885c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1886c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectSuccessfulBackgroundScan(order, nativeScanSettings, results);
1887c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1888c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1889c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    /**
189005d51a2d8eb67ea2eaf4cae43280d1cf9fe92645Ningyuan Wang     * Tests wificond PNO scan when the PNO scan results contain IE info. This ensures that the
1891c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * PNO scan results are plumbed back to the client as a PNO network found event.
1892c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     */
1893c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    @Test
1894c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    public void testSuccessfulHwPnoScanWithNoBackgroundScan() throws Exception {
1895c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        startServiceAndLoadDriver();
1896e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
1897c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Handler handler = mock(Handler.class);
1898c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1899c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
1900c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int requestId = 12;
1901c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1902c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ScanResults scanResults = createScanResultsForPno();
1903c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
1904c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForHwPno();
1905c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
1906c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createPnoSettings(scanResults);
1907c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1908c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
1909c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectHwPnoScanWithNoBackgroundScan(order, handler, requestId, pnoSettings.second,
1910c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                scanResults);
1911d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults());
1912c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1913c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1914c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    /**
1915c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * Tests Hal ePNO scan when the PNO scan results contain IE info. This ensures that the
1916c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * PNO scan results are plumbed back to the client as a PNO network found event.
1917c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     */
1918c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    @Test
1919c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    public void testSuccessfulHwPnoScanWithBackgroundScan() throws Exception {
1920c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        startServiceAndLoadDriver();
1921e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
1922c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Handler handler = mock(Handler.class);
1923c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1924c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
1925c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int requestId = 12;
1926c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1927c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ScanResults scanResults = createScanResultsForPno();
1928c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
1929c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForHwPno();
1930c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
1931c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createPnoSettings(scanResults);
1932c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1933c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
1934c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectHwPnoScanWithBackgroundScan(order, handler, requestId, scanSettings.second,
1935c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                pnoSettings.second, scanResults);
1936d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults());
1937c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1938c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1939c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    /**
1940c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * Tests Hal ePNO scan when the PNO scan results don't contain IE info. This ensures that the
1941c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * single scan results are plumbed back to the client as a PNO network found event.
1942c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     */
1943c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    @Test
1944c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    public void testSuccessfulHwPnoScanWithBackgroundScanWithNoIE() throws Exception {
1945c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        startServiceAndLoadDriver();
1946e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
1947c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Handler handler = mock(Handler.class);
1948c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1949c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
1950c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int requestId = 12;
1951c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1952c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ScanResults scanResults = createScanResultsForPnoWithNoIE();
1953c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
1954c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForHwPno();
1955c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
1956c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createPnoSettings(scanResults);
1957c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1958c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
1959c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectHwPnoScanWithBackgroundScanWithNoIE(order, handler, requestId, scanSettings.second,
1960c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                computeSingleScanNativeSettings(scanSettings.first), pnoSettings.second,
1961c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                scanResults);
1962c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1963c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ArrayList<ScanResult> sortScanList =
1964c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                new ArrayList<ScanResult>(Arrays.asList(scanResults.getRawScanResults()));
1965c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Collections.sort(sortScanList, WifiScannerImpl.SCAN_RESULT_SORT_COMPARATOR);
1966d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyPnoNetworkFoundReceived(order, handler, requestId,
1967c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                sortScanList.toArray(new ScanResult[sortScanList.size()]));
1968c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1969c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1970c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    /**
1971c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * Tests SW PNO scan. This ensures that the background scan results are plumbed back to the
1972c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * client as a PNO network found event.
1973c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     */
1974c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    @Test
1975c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    public void testSuccessfulSwPnoScan() throws Exception {
1976c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        startServiceAndLoadDriver();
1977e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
1978c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Handler handler = mock(Handler.class);
1979c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1980c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
1981c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int requestId = 12;
1982c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1983c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ScanResults scanResults = createScanResultsForPno();
1984c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
1985c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForSwPno();
1986c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
1987c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createPnoSettings(scanResults);
1988c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1989c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
1990c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectSwPnoScan(order, scanSettings.second, scanResults);
1991d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults());
1992c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
19935382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
19945382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius    /**
19955382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius     * Tries to simulate the race scenario where a client is disconnected immediately after single
19965382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius     * scan request is sent to |SingleScanStateMachine|.
19975382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius     */
19985382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius    @Test
19995382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius    public void processSingleScanRequestAfterDisconnect() throws Exception {
20005382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        startServiceAndLoadDriver();
2001e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
20025382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class));
20035382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        mLooper.dispatchAll();
20045382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
20055382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // Send the single scan request and then send the disconnect immediately after.
20065382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
20075382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
20085382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        int requestId = 10;
20095382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
20105382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
20115382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // Can't call |disconnect| here because that sends |CMD_CHANNEL_DISCONNECT| followed by
20125382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // |CMD_CHANNEL_DISCONNECTED|.
2013c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        controlChannel.sendMessage(Message.obtain(null, AsyncChannel.CMD_CHANNEL_DISCONNECTED,
2014c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                        AsyncChannel.STATUS_REMOTE_DISCONNECTION, 0, null));
20155382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
20165382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // Now process the above 2 actions. This should result in first processing the single scan
20175382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // request (which forwards the request to SingleScanStateMachine) and then processing the
20185382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // disconnect after.
20195382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        mLooper.dispatchAll();
20205382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
20215382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // Now check that we logged the invalid request.
20225382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        String serviceDump = dumpService();
20235382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        Pattern logLineRegex = Pattern.compile("^.+" + "singleScanInvalidRequest: "
20245382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius                + "ClientInfo\\[unknown\\],Id=" + requestId + ",bad request$", Pattern.MULTILINE);
20255382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        assertTrue("dump did not contain log with ClientInfo[unknown]: " + serviceDump + "\n",
20265382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius                logLineRegex.matcher(serviceDump).find());
20275382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius    }
20285382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
2029c9c91fd93350151a33d87fca768921520c256256Mitchell Wills    /**
2030c9c91fd93350151a33d87fca768921520c256256Mitchell Wills     * Tries to simulate the race scenario where a client is disconnected immediately after single
2031c9c91fd93350151a33d87fca768921520c256256Mitchell Wills     * scan request is sent to |SingleScanStateMachine|.
2032c9c91fd93350151a33d87fca768921520c256256Mitchell Wills     */
2033c9c91fd93350151a33d87fca768921520c256256Mitchell Wills    @Test
2034c9c91fd93350151a33d87fca768921520c256256Mitchell Wills    public void sendScanRequestAfterUnsuccessfulSend() throws Exception {
2035c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
2036c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
2037c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        int requestId = 9;
2038c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
2039c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        startServiceAndLoadDriver();
2040e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao        mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
2041c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        Handler handler = mock(Handler.class);
2042c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
2043c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
2044c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
2045c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
2046c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
2047c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        ScanResults results = ScanResults.create(0, 2400);
2048c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
2049c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                .thenReturn(results.getRawScanData());
2050c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
2051c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        InOrder order = inOrder(mWifiScannerImpl, handler);
2052c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
2053c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
2054c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
2055c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(order,
2056c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                computeSingleScanNativeSettings(requestSettings));
2057c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifySuccessfulResponse(order, handler, requestId);
2058c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
2059c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
2060c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
2061c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
2062c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifySingleScanCompletedReceived(order, handler, requestId);
2063c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifyNoMoreInteractions(handler);
2064c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
2065c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        controlChannel.sendMessage(Message.obtain(null, AsyncChannel.CMD_CHANNEL_DISCONNECTED,
2066c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                        AsyncChannel.STATUS_SEND_UNSUCCESSFUL, 0, null));
2067c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
2068c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
2069c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
2070c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
2071c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(order,
2072c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                computeSingleScanNativeSettings(requestSettings));
2073c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifySuccessfulResponse(order, handler, requestId);
2074c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
2075c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
2076c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
2077c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
2078c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifySingleScanCompletedReceived(order, handler, requestId);
2079c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifyNoMoreInteractions(handler);
2080c9c91fd93350151a33d87fca768921520c256256Mitchell Wills    }
208194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills}
2082