WifiScanningServiceTest.java revision 4fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0
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.*;
200ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills
210ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Willsimport static org.junit.Assert.*;
221345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Willsimport static org.mockito.Matchers.*;
230ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Willsimport static org.mockito.Mockito.*;
2494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
25f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wileyimport android.app.test.MockAnswerUtil.AnswerWithArguments;
26107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhneimport android.app.test.TestAlarmManager;
2794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.content.BroadcastReceiver;
2894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.content.Context;
296c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silbersteinimport android.content.Intent;
3094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.content.IntentFilter;
31c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Piusimport android.net.wifi.ScanResult;
3294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.net.wifi.WifiManager;
3394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.net.wifi.WifiScanner;
341345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Willsimport android.os.Binder;
350ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Willsimport android.os.Bundle;
3694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.os.Handler;
3794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport android.os.Looper;
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;
52a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.ScanResults;
53a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.TestUtil;
54a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiInjector;
55a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiMetrics;
56a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiMetricsProto;
57a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiNative;
5894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
5994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.junit.After;
6094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.junit.Before;
6194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.junit.Test;
6294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.mockito.ArgumentCaptor;
63d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Willsimport org.mockito.InOrder;
6494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.mockito.Mock;
6594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport org.mockito.MockitoAnnotations;
664fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Raoimport org.mockito.Spy;
678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Willsimport org.mockito.internal.matchers.CapturingMatcher;
6894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
69d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Willsimport java.io.FileDescriptor;
70d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Willsimport java.io.PrintWriter;
71d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Willsimport java.io.StringWriter;
72c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Piusimport java.util.ArrayList;
73c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Piusimport java.util.Arrays;
74c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Piusimport java.util.Collections;
75d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silbersteinimport java.util.List;
76d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Willsimport java.util.regex.Pattern;
77c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
7894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills/**
79a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills * Unit tests for {@link com.android.server.wifi.scanner.WifiScanningServiceImpl}.
8094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills */
8194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills@SmallTest
8294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willspublic class WifiScanningServiceTest {
8394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public static final String TAG = "WifiScanningServiceTest";
8494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
851b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    private static final int TEST_MAX_SCAN_BUCKETS_IN_CAPABILITIES = 8;
861b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius
8794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Mock Context mContext;
88f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley    TestAlarmManager mAlarmManager;
8994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Mock WifiScannerImpl mWifiScannerImpl;
9094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Mock WifiScannerImpl.WifiScannerImplFactory mWifiScannerImplFactory;
9194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Mock IBatteryStats mBatteryStats;
92c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    @Mock WifiInjector mWifiInjector;
93107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne    @Mock Clock mClock;
944fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Rao    @Spy FakeWifiLog mLog;
95c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    WifiMetrics mWifiMetrics;
96f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley    TestLooper mLooper;
9794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    WifiScanningServiceImpl mWifiScanningServiceImpl;
9894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
99c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
10094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Before
10194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void setUp() throws Exception {
10294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        MockitoAnnotations.initMocks(this);
10394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
104f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley        mAlarmManager = new TestAlarmManager();
1058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mContext.getSystemService(Context.ALARM_SERVICE))
1068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(mAlarmManager.getAlarmManager());
107107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne        mWifiMetrics = new WifiMetrics(mClock);
1088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
109e6d8fa5fb50afdfc04922f7f87c2cac08db5bbecMitchell Wills        ChannelHelper channelHelper = new PresetKnownBandsChannelHelper(
11094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                new int[]{2400, 2450},
11194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                new int[]{5150, 5175},
11294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                new int[]{5600, 5650, 5660});
11394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
114f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley        mLooper = new TestLooper();
115ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius        when(mWifiScannerImplFactory
116ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius                .create(any(Context.class), any(Looper.class), any(Clock.class)))
11794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                .thenReturn(mWifiScannerImpl);
1187e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills        when(mWifiScannerImpl.getChannelHelper()).thenReturn(channelHelper);
119c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
1204fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Rao        when(mWifiInjector.makeLog(anyString())).thenReturn(mLog);
12194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mWifiScanningServiceImpl = new WifiScanningServiceImpl(mContext, mLooper.getLooper(),
122c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiScannerImplFactory, mBatteryStats, mWifiInjector);
12394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
12494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
12594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @After
12694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void cleanup() {
12794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        validateMockitoUsage();
12894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
12994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
130d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    /**
131d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills     * Internal BroadcastReceiver that WifiScanningServiceImpl uses to listen for broadcasts
132d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills     * this is initialized by calling startServiceAndLoadDriver
133d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills     */
134d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    BroadcastReceiver mBroadcastReceiver;
13594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
13694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    private WifiScanner.ScanSettings generateValidScanSettings() {
13794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        return createRequest(WifiScanner.WIFI_BAND_BOTH, 30000, 0, 20,
13894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
13994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
14094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
14194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    private BidirectionalAsyncChannel connectChannel(Handler handler) {
14294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        BidirectionalAsyncChannel controlChannel = new BidirectionalAsyncChannel();
14394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        controlChannel.connect(mLooper.getLooper(), mWifiScanningServiceImpl.getMessenger(),
14494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                handler);
14594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mLooper.dispatchAll();
14694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        controlChannel.assertConnected();
14794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        return controlChannel;
14894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
14994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
1505751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler) {
15194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
152d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        order.verify(handler).handleMessage(messageCaptor.capture());
15394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        return messageCaptor.getValue();
15494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
15594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
1565751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler,
1578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            final int what) {
1588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        CapturingMatcher<Message> messageMatcher = new CapturingMatcher<Message>() {
1598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            public boolean matches(Object argument) {
1608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                Message message = (Message) argument;
1618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                return message.what == what;
1628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            }
1638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        };
1648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        order.verify(handler).handleMessage(argThat(messageMatcher));
1658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        return messageMatcher.getLastValue();
1668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
1678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
168d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    private static void verifyScanResultsReceived(InOrder order, Handler handler, int listenerId,
169d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            WifiScanner.ScanData... expected) {
1708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler,
1718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                WifiScanner.CMD_SCAN_RESULT);
172d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertScanResultsMessage(listenerId, expected, scanResultMessage);
173d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
174d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
1755751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void assertScanResultsMessage(int listenerId, WifiScanner.ScanData[] expected,
176d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            Message scanResultMessage) {
177d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertEquals("what", WifiScanner.CMD_SCAN_RESULT, scanResultMessage.what);
178d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertEquals("listenerId", listenerId, scanResultMessage.arg2);
179d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertScanDatasEquals(expected,
180d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                ((WifiScanner.ParcelableScanData) scanResultMessage.obj).getResults());
181d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
182d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
183d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    private static void verifySingleScanCompletedReceived(InOrder order, Handler handler,
1845751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            int listenerId) {
1858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Message completedMessage = verifyHandleMessageAndGetMessage(order, handler,
1868adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                WifiScanner.CMD_SINGLE_SCAN_COMPLETED);
1878adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertSingleScanCompletedMessage(listenerId, completedMessage);
1888adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
1898adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
1905751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void assertSingleScanCompletedMessage(int listenerId, Message completedMessage) {
1918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertEquals("what", WifiScanner.CMD_SINGLE_SCAN_COMPLETED, completedMessage.what);
1928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertEquals("listenerId", listenerId, completedMessage.arg2);
1938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
1948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
1955751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void sendBackgroundScanRequest(BidirectionalAsyncChannel controlChannel,
1960ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills            int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) {
1970ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        Bundle scanParams = new Bundle();
1980ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
1990ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        scanParams.putParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY, workSource);
200d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_BACKGROUND_SCAN, 0,
2010ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills                        scanRequestId, scanParams));
202d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
203d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
2045751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void sendSingleScanRequest(BidirectionalAsyncChannel controlChannel,
2050ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills            int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) {
2060ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        Bundle scanParams = new Bundle();
2070ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
2080ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        scanParams.putParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY, workSource);
2098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_SINGLE_SCAN, 0,
2100ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills                        scanRequestId, scanParams));
2118adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
2128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
2131ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    private static void registerScanListener(BidirectionalAsyncChannel controlChannel,
2141ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int listenerRequestId) {
2151ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_REGISTER_SCAN_LISTENER, 0,
2161ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        listenerRequestId, null));
2171ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
2181ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
2191ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    private static void deregisterScanListener(BidirectionalAsyncChannel controlChannel,
2201ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int listenerRequestId) {
2211ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_DEREGISTER_SCAN_LISTENER, 0,
2221ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        listenerRequestId, null));
2231ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
2241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
2255751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void verifySuccessfulResponse(InOrder order, Handler handler, int arg2) {
226d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        Message response = verifyHandleMessageAndGetMessage(order, handler);
227d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertSuccessfulResponse(arg2, response);
22894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
22994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
2305751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void assertSuccessfulResponse(int arg2, Message response) {
231d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        if (response.what == WifiScanner.CMD_OP_FAILED) {
232d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj;
233d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            fail("response indicates failure, reason=" + result.reason
234d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                    + ", description=" + result.description);
235d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        } else {
236d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.what", WifiScanner.CMD_OP_SUCCEEDED, response.what);
237d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.arg2", arg2, response.arg2);
238d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        }
239d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
240d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
2415751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    /**
2425751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * If multiple results are expected for a single hardware scan then the order that they are
2435751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * dispatched is dependant on the order which they are iterated through internally. This
2441ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * function validates that the order is either one way or the other. A scan listener can
2451ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * optionally be provided as well and will be checked after the after the single scan requests.
2465751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     */
2475751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void verifyMultipleSingleScanResults(InOrder handlerOrder, Handler handler,
2481ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int requestId1, ScanResults results1, int requestId2, ScanResults results2,
2491ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int listenerRequestId, ScanResults listenerResults) {
2505751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
2511ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        handlerOrder.verify(handler, times(listenerResults == null ? 4 : 5))
2525751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                .handleMessage(messageCaptor.capture());
2535751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int firstListenerId = messageCaptor.getAllValues().get(0).arg2;
2545751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertTrue(firstListenerId + " was neither " + requestId2 + " nor " + requestId1,
2555751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                firstListenerId == requestId2 || firstListenerId == requestId1);
2565751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        if (firstListenerId == requestId2) {
2575751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertScanResultsMessage(requestId2,
2585751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    new WifiScanner.ScanData[] {results2.getScanData()},
2595751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    messageCaptor.getAllValues().get(0));
2605751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(1));
2615751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertScanResultsMessage(requestId1,
2625751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    new WifiScanner.ScanData[] {results1.getScanData()},
2635751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    messageCaptor.getAllValues().get(2));
2645751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertSingleScanCompletedMessage(requestId1, messageCaptor.getAllValues().get(3));
2651ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            if (listenerResults != null) {
2661ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                assertScanResultsMessage(listenerRequestId,
2671ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        new WifiScanner.ScanData[] {listenerResults.getScanData()},
2681ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        messageCaptor.getAllValues().get(4));
2691ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            }
2705751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        } else {
2715751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertScanResultsMessage(requestId1,
2725751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    new WifiScanner.ScanData[] {results1.getScanData()},
2735751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    messageCaptor.getAllValues().get(0));
2745751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertSingleScanCompletedMessage(requestId1, messageCaptor.getAllValues().get(1));
2755751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertScanResultsMessage(requestId2,
2765751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    new WifiScanner.ScanData[] {results2.getScanData()},
2775751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                    messageCaptor.getAllValues().get(2));
2785751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills            assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(3));
2791ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            if (listenerResults != null) {
2801ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                assertScanResultsMessage(listenerRequestId,
2811ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        new WifiScanner.ScanData[] {listenerResults.getScanData()},
2821ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        messageCaptor.getAllValues().get(4));
2831ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            }
2845751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        }
2855751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    }
2865751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
2871ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    private static void verifyMultipleSingleScanResults(InOrder handlerOrder, Handler handler,
2881ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills            int requestId1, ScanResults results1, int requestId2, ScanResults results2) {
2891ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId2,
2901ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                results2, -1, null);
2911ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
2921ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
2935751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void verifyFailedResponse(InOrder order, Handler handler, int arg2,
29494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills            int expectedErrorReason, String expectedErrorDescription) {
295d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        Message response = verifyHandleMessageAndGetMessage(order, handler);
296d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertFailedResponse(arg2, expectedErrorReason, expectedErrorDescription, response);
29794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
29894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
2995751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    private static void assertFailedResponse(int arg2, int expectedErrorReason,
30094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills            String expectedErrorDescription, Message response) {
301d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        if (response.what == WifiScanner.CMD_OP_SUCCEEDED) {
302d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            fail("response indicates success");
303d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        } else {
304d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.what", WifiScanner.CMD_OP_FAILED, response.what);
305d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.arg2", arg2, response.arg2);
306d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj;
307d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.obj.reason",
308d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                    expectedErrorReason, result.reason);
309d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills            assertEquals("response.obj.description",
310d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                    expectedErrorDescription, result.description);
311d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        }
312d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
313d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
3148adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    private WifiNative.ScanEventHandler verifyStartSingleScan(InOrder order,
3158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            WifiNative.ScanSettings expected) {
3168adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor =
3178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                ArgumentCaptor.forClass(WifiNative.ScanSettings.class);
3188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor =
3198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class);
3208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        order.verify(mWifiScannerImpl).startSingleScan(scanSettingsCaptor.capture(),
3218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                scanEventHandlerCaptor.capture());
3228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue());
3238adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        return scanEventHandlerCaptor.getValue();
3248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
3258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
326c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private WifiNative.ScanEventHandler verifyStartBackgroundScan(InOrder order,
327c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.ScanSettings expected) {
328d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor =
329d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                ArgumentCaptor.forClass(WifiNative.ScanSettings.class);
330c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor =
331c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class);
332d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        order.verify(mWifiScannerImpl).startBatchedScan(scanSettingsCaptor.capture(),
333c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                scanEventHandlerCaptor.capture());
334d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue());
335c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return scanEventHandlerCaptor.getValue();
33694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
33794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
3388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    private static final int MAX_AP_PER_SCAN = 16;
33994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    private void startServiceAndLoadDriver() {
34094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mWifiScanningServiceImpl.startService();
3411b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        setupAndLoadDriver(TEST_MAX_SCAN_BUCKETS_IN_CAPABILITIES);
3423040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    }
3433040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
3441b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    private void setupAndLoadDriver(int max_scan_buckets) {
34594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        when(mWifiScannerImpl.getScanCapabilities(any(WifiNative.ScanCapabilities.class)))
34694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                .thenAnswer(new AnswerWithArguments() {
34794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        public boolean answer(WifiNative.ScanCapabilities capabilities) {
34894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            capabilities.max_scan_cache_size = Integer.MAX_VALUE;
3491b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius                            capabilities.max_scan_buckets = max_scan_buckets;
3508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                            capabilities.max_ap_cache_per_scan = MAX_AP_PER_SCAN;
35194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            capabilities.max_rssi_sample_size = 8;
35294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            capabilities.max_scan_reporting_threshold = 10;
35394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            capabilities.max_hotlist_bssids = 0;
35494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            capabilities.max_significant_wifi_change_aps = 0;
35594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                            return true;
35694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        }
35794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                    });
358d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
359d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                ArgumentCaptor.forClass(BroadcastReceiver.class);
36094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        verify(mContext)
361d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                .registerReceiver(broadcastReceiverCaptor.capture(), any(IntentFilter.class));
362d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        mBroadcastReceiver = broadcastReceiverCaptor.getValue();
36368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        TestUtil.sendWifiScanAvailable(broadcastReceiverCaptor.getValue(), mContext,
36468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                WifiManager.WIFI_STATE_ENABLED);
36594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mLooper.dispatchAll();
36694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
36794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
368d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills    private String dumpService() {
369d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        StringWriter stringWriter = new StringWriter();
370d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        mWifiScanningServiceImpl.dump(new FileDescriptor(), new PrintWriter(stringWriter),
371d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills                new String[0]);
372d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        return stringWriter.toString();
373d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills    }
374d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills
375d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills    private void assertDumpContainsRequestLog(String type, int id) {
376d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        String serviceDump = dumpService();
3779e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills        Pattern logLineRegex = Pattern.compile("^.+" + type
3789e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills                + ": ClientInfo\\[uid=\\d+,android\\.os\\.Messenger@[a-f0-9]+\\],Id=" + id
3799e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills                + ".*$", Pattern.MULTILINE);
380d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        assertTrue("dump did not contain log with type=" + type + ", id=" + id +
38159298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                ": " + serviceDump + "\n",
38259298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                logLineRegex.matcher(serviceDump).find());
3833219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    }
38459298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills
38559298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills    private void assertDumpContainsCallbackLog(String callback, int id, String extra) {
38659298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        String serviceDump = dumpService();
38759298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        String extraPattern = extra == null ? "" : "," + extra;
3889e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills        Pattern logLineRegex = Pattern.compile("^.+" + callback
3899e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills                + ": ClientInfo\\[uid=\\d+,android\\.os\\.Messenger@[a-f0-9]+\\],Id=" + id
3909e7f5e0a47a9a4aa519a50d9a0959547c1c604f1Mitchell Wills                + extraPattern + "$", Pattern.MULTILINE);
39159298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertTrue("dump did not contain callback log with callback=" + callback + ", id=" + id +
39259298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                ", extra=" + extra + ": " + serviceDump + "\n",
393d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills                logLineRegex.matcher(serviceDump).find());
3943219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    }
395d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills
39694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Test
39794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void construct() throws Exception {
3988adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyNoMoreInteractions(mWifiScannerImpl, mWifiScannerImpl,
39994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                mWifiScannerImplFactory, mBatteryStats);
400d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        dumpService(); // make sure this succeeds
40194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
40294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
40394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Test
40494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void startService() throws Exception {
40594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        mWifiScanningServiceImpl.startService();
40694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        verifyNoMoreInteractions(mWifiScannerImplFactory);
40794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
40894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        Handler handler = mock(Handler.class);
40994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
410d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        InOrder order = inOrder(handler);
4110ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendBackgroundScanRequest(controlChannel, 122, generateValidScanSettings(), null);
412d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        mLooper.dispatchAll();
413d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        verifyFailedResponse(order, handler, 122, WifiScanner.REASON_UNSPECIFIED, "not available");
41494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
41594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
41694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Test
4173040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    public void disconnectClientBeforeWifiEnabled() throws Exception {
4183040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mWifiScanningServiceImpl.startService();
4193040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4203040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class));
4213040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4223040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4233040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        controlChannel.disconnect();
4243040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4253040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    }
4263040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4273040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    @Test
42894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void loadDriver() throws Exception {
42994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        startServiceAndLoadDriver();
430ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius        verify(mWifiScannerImplFactory, times(1))
431ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius                .create(any(Context.class), any(Looper.class), any(Clock.class));
43294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
43394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        Handler handler = mock(Handler.class);
43494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
435d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        InOrder order = inOrder(handler);
43694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
43794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
4380ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendBackgroundScanRequest(controlChannel, 192, generateValidScanSettings(), null);
439d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        mLooper.dispatchAll();
440d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        verifySuccessfulResponse(order, handler, 192);
441d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        assertDumpContainsRequestLog("addBackgroundScanRequest", 192);
44294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
44394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
44494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    @Test
4453040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    public void disconnectClientAfterStartingWifi() throws Exception {
4463040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mWifiScanningServiceImpl.startService();
4473040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4483040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class));
4493040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4503040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4511b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        setupAndLoadDriver(TEST_MAX_SCAN_BUCKETS_IN_CAPABILITIES);
4523040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4533040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        controlChannel.disconnect();
4543040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4553040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    }
4563040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4573040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    @Test
4583040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    public void connectAndDisconnectClientAfterStartingWifi() throws Exception {
4593040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        startServiceAndLoadDriver();
4603040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4613040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class));
4623040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4633040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        controlChannel.disconnect();
4643040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills        mLooper.dispatchAll();
4653040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    }
4663040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills
4673040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    @Test
46894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    public void sendInvalidCommand() throws Exception {
46994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        startServiceAndLoadDriver();
47094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
47194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        Handler handler = mock(Handler.class);
47294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
473d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
474d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        controlChannel.sendMessage(Message.obtain(null, Protocol.BASE_WIFI_MANAGER));
475d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        mLooper.dispatchAll();
476d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills        verifyFailedResponse(order, handler, 0, WifiScanner.REASON_INVALID_REQUEST,
477d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills                "Invalid request");
47894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    }
4798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
4801b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    @Test
4811b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    public void rejectBackgroundScanRequestWhenHalReturnsInvalidCapabilities() throws Exception {
4821b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        mWifiScanningServiceImpl.startService();
4831b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        setupAndLoadDriver(0);
4841b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius
4851b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        Handler handler = mock(Handler.class);
4861b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
4871b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        InOrder order = inOrder(handler);
4881b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        sendBackgroundScanRequest(controlChannel, 122, generateValidScanSettings(), null);
4891b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        mLooper.dispatchAll();
4901b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius        verifyFailedResponse(order, handler, 122, WifiScanner.REASON_UNSPECIFIED, "not available");
4911b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius    }
4921b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius
4938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    private void doSuccessfulSingleScan(WifiScanner.ScanSettings requestSettings,
4941345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills            WifiNative.ScanSettings nativeSettings, ScanResults results) throws RemoteException {
4958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId = 12;
4961345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource = new WorkSource(2292);
4978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
4988adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
4998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
5008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
5018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
5028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
5048adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
5058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5061345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, workSource);
5078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
5098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings);
5108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
5111345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource));
5128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
514f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                .thenReturn(results.getRawScanData());
5158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
5168adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
518d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
519d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId);
5206c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
5218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyNoMoreInteractions(handler);
5221345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource));
523d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId);
52459298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId,
525f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                "results=" + results.getScanData().getResults().length);
5268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
5278adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
5298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a single scan for a band and verify that it is successful.
5308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
5318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
5328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanBandRequest() throws Exception {
5333219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
5343219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
5358adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
5363219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                ScanResults.create(0, true, 2400, 5150, 5175));
5378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
5388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
5408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a single scan for a list of channels and verify that it is successful.
5418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
5428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
5438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanChannelsRequest() throws Exception {
5443219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400, 5150, 5175),
5453219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
5468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
5478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                ScanResults.create(0, 2400, 5150, 5175));
5488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
5498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
5513219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills     * Do a single scan for a list of all channels and verify that it is successful.
5523219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills     */
5533219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    @Test
5543219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    public void sendSingleScanAllChannelsRequest() throws Exception {
5553219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(
5563219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                channelsToSpec(2400, 2450, 5150, 5175, 5600, 5650, 5660),
5573219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
5583219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
5593219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills                ScanResults.create(0, true, 2400, 5150, 5175));
5603219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    }
5613219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills
5623219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills    /**
563f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     * Do a single scan with no results and verify that it is successful.
564f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     */
565f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    @Test
566f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    public void sendSingleScanRequestWithNoResults() throws Exception {
567f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
568f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
569f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
570f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                ScanResults.create(0, new int[0]));
571f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    }
572f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills
573f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    /**
574f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     * Do a single scan with results that do not match the requested scan and verify that it is
575f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     * still successful (and returns no results).
576f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills     */
577f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    @Test
578f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    public void sendSingleScanRequestWithBadRawResults() throws Exception {
579f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_24_GHZ, 0,
580f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
581f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        // Create a set of scan results that has results not matching the request settings, but is
582f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        // limited to zero results for the expected results.
583f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        ScanResults results = ScanResults.createOverflowing(0, 0,
584f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                ScanResults.generateNativeResults(0, 5150, 5171));
585f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
586f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills                results);
587f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    }
588f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills
589f5cdd8e7a6b7d4c0b5f77134273c7e894d8c087bMitchell Wills    /**
5908adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a single scan, which the hardware fails to start, and verify that a failure response is
5918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * delivered.
5928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
5938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
5948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanRequestWhichFailsToStart() throws Exception {
5958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
5968adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
5978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId = 33;
5988adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
5998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
6008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
6028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
6038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
6048adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // scan fails
6068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
6078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(false);
6088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6090ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
6108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6118adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
6128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Scan is successfully queue, but then fails to execute
6138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
6148adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        order.verify(handler, times(2)).handleMessage(messageCaptor.capture());
6158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertSuccessfulResponse(requestId, messageCaptor.getAllValues().get(0));
6168adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        assertFailedResponse(requestId, WifiScanner.REASON_UNSPECIFIED,
6178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                "Failed to start single scan", messageCaptor.getAllValues().get(1));
6181345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verifyNoMoreInteractions(mBatteryStats);
619c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
620c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getOneshotScanCount(), 1);
621c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1);
622d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId);
6238adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
6248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
6268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a single scan, which successfully starts, but fails partway through and verify that a
6278adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * failure response is delivered.
6288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
6298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
6308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanRequestWhichFailsAfterStart() throws Exception {
6318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
6328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
6338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId = 33;
6341345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource = new WorkSource(Binder.getCallingUid()); // don't explicitly set
6358adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6368adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
6378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
6398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
6408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
6418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // successful start
6438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
6448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
6458adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6460ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
6478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Scan is successfully queue
6498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
6508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler =
6518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                verifyStartSingleScan(order, computeSingleScanNativeSettings(requestSettings));
6528adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
6531345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource));
6548adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6558adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // but then fails to execute
6568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_FAILED);
6578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
6588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyFailedResponse(order, handler, requestId,
6598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                WifiScanner.REASON_UNSPECIFIED, "Scan failed");
66056820e92fd4b1a0cee83f552905fc76fc8290146Mitchell Wills        assertDumpContainsCallbackLog("singleScanFailed", requestId,
66156820e92fd4b1a0cee83f552905fc76fc8290146Mitchell Wills                "reason=" + WifiScanner.REASON_UNSPECIFIED + ", Scan failed");
662c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getOneshotScanCount(), 1);
663c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1);
6641345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource));
6656c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
6668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
6678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
6681ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
6691ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Send a single scan request and then disable Wi-Fi before it completes
6701ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
6711ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
6721ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    public void sendSingleScanRequestThenDisableWifi() {
6731ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400), 0,
6741ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
6751ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId = 2293;
6761ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
6771ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
6781ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
6791ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
6801ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
6811ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
6821ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
6831ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
6841ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
6851ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
6861ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Run scan 1
6871ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
6881ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
6891ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
6901ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
6911ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // disable wifi
6921ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext,
6931ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                WifiManager.WIFI_STATE_DISABLED);
6941ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
6951ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // validate failed response
6961ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
6971ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyFailedResponse(order, handler, requestId, WifiScanner.REASON_UNSPECIFIED,
6981ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "Scan was interrupted");
6991ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyNoMoreInteractions(handler);
7001ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
7011ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7021ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
7031ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Send a single scan request, schedule a second pending scan and disable Wi-Fi before the first
7041ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * scan completes.
7051ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
7061ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
7071ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    public void sendSingleScanAndPendingScanAndListenerThenDisableWifi() {
7081ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
7091ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
7101ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId1 = 2293;
7111ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7121ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450), 0,
7131ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
7141ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId2 = 2294;
7151ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7161ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int listenerRequestId = 2295;
7171ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7181ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
7191ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7201ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
7211ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
7221ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7231ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
7241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
7251ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
7261ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7271ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Request scan 1
7281ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
7291ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7301ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId1);
7311ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7321ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Request scan 2
7331ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
7341ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7351ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId2);
7361ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7371ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Setup scan listener
7381ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        registerScanListener(controlChannel, listenerRequestId);
7391ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7401ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, listenerRequestId);
7411ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7421ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // disable wifi
7431ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        TestUtil.sendWifiScanAvailable(mBroadcastReceiver, mContext,
7441ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                WifiManager.WIFI_STATE_DISABLED);
7451ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
7461ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // validate failed response
7471ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
7481ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
7491ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        order.verify(handler, times(2)).handleMessage(messageCaptor.capture());
7501ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertFailedResponse(requestId1, WifiScanner.REASON_UNSPECIFIED,
7511ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "Scan was interrupted", messageCaptor.getAllValues().get(0));
7521ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertFailedResponse(requestId2, WifiScanner.REASON_UNSPECIFIED,
7531ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "Scan was interrupted", messageCaptor.getAllValues().get(1));
7541ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // No additional callbacks for scan listener
7551ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyNoMoreInteractions(handler);
7561ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
7578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
7598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Send a single scan request and then a second one after the first completes.
7608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
7618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
7628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanRequestAfterPreviousCompletes() {
7638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
7648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
7658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId1 = 12;
7668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ScanResults results1 = ScanResults.create(0, 2400);
7678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
7708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
7718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId2 = 13;
7728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ScanResults results2 = ScanResults.create(0, 2450);
7738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
7768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
7788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
7798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
7818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
7826c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl, mContext);
7838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7848adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Run scan 1
7850ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
7868adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7878adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
7888adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(order,
7898adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings1));
7908adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, requestId1);
7918adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 1 results
7938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
7948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results1.getScanData());
7958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
7968adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
7978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
7986c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // Note: The order of the following verification calls looks out of order if you compare to
7996c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // the source code of WifiScanningServiceImpl WifiSingleScanStateMachine.reportScanResults.
8006c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // This is due to the fact that verifyScanResultsReceived and
8016c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // verifySingleScanCompletedReceived require an additional call to handle the message that
8026c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // is created in reportScanResults.  This handling is done in the two verify*Received calls
8036c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        // that is run AFTER the reportScanResults method in WifiScanningServiceImpl completes.
8046c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        order.verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
805d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId1, results1.getScanData());
806d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId1);
8078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Run scan 2
8090ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
8108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8118adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(order,
8138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings2));
8148adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, requestId2);
8158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8168adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 2 results
8178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
8188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results2.getScanData());
8198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
8208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8226c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        order.verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
823d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId2, results2.getScanData());
824d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId2);
8258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
8268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8278adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
8285751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * Send a single scan request and then a second one not satisfied by the first before the first
8295751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * completes. Verify that both are scheduled and succeed.
8308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
8318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
8328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendSingleScanRequestWhilePreviousScanRunning() {
8338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
8348adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
8358adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId1 = 12;
8368adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ScanResults results1 = ScanResults.create(0, 2400);
8378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
8398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
8408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId2 = 13;
8418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ScanResults results2 = ScanResults.create(0, 2450);
8428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
8458adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
8478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
8488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8498adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
8508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
8518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder handlerOrder = inOrder(handler);
8528adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
8538adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8548adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Run scan 1
8550ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
8568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
8598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings1));
8608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
8618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Queue scan 2 (will not run because previous is in progress)
8630ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
8648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
8658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
8668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8678adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 1 results
8688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
8698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results1.getScanData());
8708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
8718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
873d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId1, results1.getScanData());
874d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId1);
8756c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
8768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // now that the first scan completed we expect the second one to start
8788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder,
8798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings2));
8808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8818adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 2 results
8828adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
8838adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results2.getScanData());
8848adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
8858adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8868adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
887d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId2, results2.getScanData());
888d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId2);
8896c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext, times(2)).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
890c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getOneshotScanCount(), 2);
891c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 2);
8928adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
8938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
8958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
8965751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * Send a single scan request and then two more before the first completes. Neither are
8975751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * satisfied by the first scan. Verify that the first completes and the second two are merged.
8988adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
8998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
9001345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills    public void sendMultipleSingleScanRequestWhilePreviousScanRunning() throws RemoteException {
9018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
9028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
9038adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId1 = 12;
9041345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource1 = new WorkSource(1121);
9058adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ScanResults results1 = ScanResults.create(0, 2400);
9068adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9078adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
9088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
9098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId2 = 13;
9101345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource2 = new WorkSource(Binder.getCallingUid()); // don't explicitly set
9118adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450);
9128adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9138adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(5150), 0,
9148adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
9158adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        int requestId3 = 15;
9161345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource3 = new WorkSource(2292);
9178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ScanResults results3 = ScanResults.create(0, 5150, 5150, 5150, 5150);
9188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanSettings nativeSettings2and3 = createSingleScanNativeSettingsForChannels(
9208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channelsToSpec(2450, 5175, 5150));
9218adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        ScanResults results2and3 = ScanResults.merge(results2, results3);
9221345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        WorkSource workSource2and3 = new WorkSource();
9231345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        workSource2and3.add(workSource2);
9241345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        workSource2and3.add(workSource3);
9258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9278adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
9288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
9308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
9318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
9338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
9348adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder handlerOrder = inOrder(handler);
9358adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
9368adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Run scan 1
9381345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, workSource1);
9398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
9418adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
9428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                computeSingleScanNativeSettings(requestSettings1));
9438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
9441345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource1));
9451345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills
9468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Queue scan 2 (will not run because previous is in progress)
9481345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        // uses uid of calling process
9490ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
9508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
9518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
9528adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9538adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // Queue scan 3 (will not run because previous is in progress)
9541345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        sendSingleScanRequest(controlChannel, requestId3, requestSettings3, workSource3);
9558adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
9568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId3);
9578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 1 results
9598adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
9608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results1.getScanData());
9618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
9628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
964d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId1, results1.getScanData());
965d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId1);
9666c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
9671345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource1));
9681345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource2and3));
9698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // now that the first scan completed we expect the second and third ones to start
9718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanEventHandler eventHandler2and3 = verifyStartSingleScan(nativeOrder,
9728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                nativeSettings2and3);
9738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        // dispatch scan 2 and 3 results
9758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
9768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .thenReturn(results2and3.getScanData());
9778adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
9788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
9808adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9815751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId2, results2, requestId3,
9825751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                results3);
983c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getOneshotScanCount(), 3);
984c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 3);
98559298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills
9861345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource2and3));
9871345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills
98859298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId1);
98959298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId2);
99059298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId3);
99159298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId1,
99259298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                "results=" + results1.getRawScanResults().length);
99359298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId2,
99459298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                "results=" + results2.getRawScanResults().length);
99559298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId3,
99659298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills                "results=" + results3.getRawScanResults().length);
9978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
9988adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
9995751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10005751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    /**
10015751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * Send a single scan request and then a second one satisfied by the first before the first
10025751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * completes. Verify that only one scan is scheduled.
10035751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     */
10045751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    @Test
10055751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    public void sendSingleScanRequestWhilePreviousScanRunningAndMergeIntoFirstScan() {
10065751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Split by frequency to make it easier to determine which results each request is expecting
10075751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results24GHz = ScanResults.create(0, 2400, 2400, 2400, 2450);
10085751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results5GHz = ScanResults.create(0, 5150, 5150, 5175);
10095751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults resultsBoth = ScanResults.merge(results24GHz, results5GHz);
10105751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10115751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
10125751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
10135751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId1 = 12;
10145751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results1 = resultsBoth;
10155751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10165751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(WifiScanner.WIFI_BAND_24_GHZ, 0,
10175751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
10185751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId2 = 13;
10195751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results2 = results24GHz;
10205751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10215751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10225751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        startServiceAndLoadDriver();
10235751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10245751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
10255751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
10265751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10275751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        Handler handler = mock(Handler.class);
10285751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
10295751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        InOrder handlerOrder = inOrder(handler);
10305751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
10315751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10325751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Run scan 1
10335751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
10345751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10355751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
10365751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(nativeOrder,
10375751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                computeSingleScanNativeSettings(requestSettings1));
10385751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
10395751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10405751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Queue scan 2 (will be folded into ongoing scan)
10415751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
10425751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
10435751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
10445751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10455751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // dispatch scan 1 results
10465751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
10475751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                .thenReturn(resultsBoth.getScanData());
10485751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
10495751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10505751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
10515751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId2,
10525751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                results2);
10535751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10545751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertEquals(mWifiMetrics.getOneshotScanCount(), 2);
10555751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 2);
10565751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    }
10575751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10585751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    /**
10595751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * Send a single scan request and then two more before the first completes, one of which is
10605751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * satisfied by the first scan. Verify that the first two complete together the second scan is
10615751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     * just for the other scan.
10625751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills     */
10635751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    @Test
10645751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    public void sendMultipleSingleScanRequestWhilePreviousScanRunningAndMergeOneIntoFirstScan()
10655751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills          throws RemoteException {
10665751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Split by frequency to make it easier to determine which results each request is expecting
10675751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results2400 = ScanResults.create(0, 2400, 2400, 2400);
10685751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results2450 = ScanResults.create(0, 2450);
10695751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results1and3 = ScanResults.merge(results2400, results2450);
10705751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10715751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400, 2450), 0,
10725751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
10735751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId1 = 12;
10745751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WorkSource workSource1 = new WorkSource(1121);
10755751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results1 = results1and3;
10765751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10775751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
10785751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
10795751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId2 = 13;
10805751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WorkSource workSource2 = new WorkSource(Binder.getCallingUid()); // don't explicitly set
10815751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450);
10825751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10835751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(2400), 0,
10845751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
10855751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        int requestId3 = 15;
10865751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WorkSource workSource3 = new WorkSource(2292);
10875751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        ScanResults results3 = results2400;
10885751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10895751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        startServiceAndLoadDriver();
10905751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10915751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
10925751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
10935751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10945751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        Handler handler = mock(Handler.class);
10955751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
10965751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        InOrder handlerOrder = inOrder(handler);
10975751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
10985751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
10995751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Run scan 1
11005751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, workSource1);
11015751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11025751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11035751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
11045751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                computeSingleScanNativeSettings(requestSettings1));
11055751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
11065751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource1));
11075751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11085751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11095751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Queue scan 2 (will not run because previous is in progress)
11105751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // uses uid of calling process
11115751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
11125751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11135751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
11145751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11155751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // Queue scan 3 (will be merged into the active scan)
11165751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        sendSingleScanRequest(controlChannel, requestId3, requestSettings3, workSource3);
11175751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11185751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId3);
11195751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11205751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // dispatch scan 1 results
11215751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
11225751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                .thenReturn(results1and3.getScanData());
11235751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
11245751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11255751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11265751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId3,
11275751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                results3);
11285751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // only the requests know at the beginning of the scan get blamed
11295751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource1));
11305751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource2));
11315751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11325751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // now that the first scan completed we expect the second and third ones to start
11335751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder,
11345751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                computeSingleScanNativeSettings(requestSettings2));
11355751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11365751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        // dispatch scan 2 and 3 results
11375751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
11385751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                .thenReturn(results2.getScanData());
11395751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
11405751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11415751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        mLooper.dispatchAll();
11425751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
1143d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId2, results2.getScanData());
1144d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId2);
11456c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext, times(2)).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
11465751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertEquals(mWifiMetrics.getOneshotScanCount(), 3);
11475751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 3);
11485751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11495751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource2));
11505751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11515751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId1);
11525751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId2);
11535751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsRequestLog("addSingleScanRequest", requestId3);
11545751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId1,
11555751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                "results=" + results1.getRawScanResults().length);
11565751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId2,
11575751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                "results=" + results2.getRawScanResults().length);
11585751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        assertDumpContainsCallbackLog("singleScanResults", requestId3,
11595751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills                "results=" + results3.getRawScanResults().length);
11605751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    }
11615751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
11621ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
1163d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * Verify that WifiService provides a way to get the most recent SingleScan results.
1164d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1165d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
1166d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void retrieveSingleScanResults() throws Exception {
1167d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiScanner.ScanSettings requestSettings =
1168d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
1169d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                              0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1170d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175);
1171d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        doSuccessfulSingleScan(requestSettings,
1172d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               computeSingleScanNativeSettings(requestSettings),
1173d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               expectedResults);
1174d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1175d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1176d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1177d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1178d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1179d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1180d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1181d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1182d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1183d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1184d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), expectedResults.getRawScanResults().length);
1185a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein
1186a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein        // Make sure that we logged the scan results in the dump method.
1187a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein        String serviceDump = dumpService();
1188a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein        Pattern logLineRegex = Pattern.compile("Latest scan results:");
1189a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein        assertTrue("dump did not contain Latest scan results: " + serviceDump + "\n",
1190a049f83a308e7753b68c1a5036ab67d9806807ecRebecca Silberstein                logLineRegex.matcher(serviceDump).find());
1191d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1192d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1193d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
1194d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * Verify that WifiService provides a way to get the most recent SingleScan results even when
1195d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * they are empty.
1196d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1197d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
1198d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void retrieveSingleScanResultsEmpty() throws Exception {
1199d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
1200d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1201d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
1202d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ScanResults.create(0, new int[0]));
1203d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1204d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1205d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1206d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1207d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1208d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1209d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1210d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1211d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1212d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1213d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1214d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1215d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), 0);
1216d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1217d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1218d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
1219d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * Verify that WifiService will return empty SingleScan results if a scan has not been
1220d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * performed.
1221d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1222d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
1223d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void retrieveSingleScanResultsBeforeAnySingleScans() throws Exception {
1224d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        startServiceAndLoadDriver();
1225d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1226d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1227d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1228d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1229d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1230d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1231d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1232d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1233d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1234d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1235d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1236d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), 0);
1237d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1238d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1239d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
1240d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * Verify that the newest scan results are returned by WifiService.getSingleScanResults.
1241d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1242d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
1243d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void retrieveMostRecentSingleScanResults() throws Exception {
1244d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
1245d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1246d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175);
1247d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        doSuccessfulSingleScan(requestSettings,
1248d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               computeSingleScanNativeSettings(requestSettings),
1249d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               expectedResults);
1250d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1251d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1252d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1253d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1254d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1255d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1256d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1257d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1258d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1259d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1260d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1261d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1262d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), expectedResults.getRawScanResults().length);
1263d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1264d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // now update with a new scan that only has one result
1265d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        int secondScanRequestId = 35;
1266d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        ScanResults expectedSingleResult = ScanResults.create(0, true, 5150);
1267d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        sendSingleScanRequest(controlChannel, secondScanRequestId, requestSettings, null);
1268d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1269d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1270d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order,
1271d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                computeSingleScanNativeSettings(requestSettings));
1272d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySuccessfulResponse(order, handler, secondScanRequestId);
1273d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1274d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // dispatch scan 2 results
1275d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        when(mWifiScannerImpl.getLatestSingleScanResults())
1276d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                .thenReturn(expectedSingleResult.getScanData());
1277d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
1278d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1279d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1280d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, secondScanRequestId,
1281d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                expectedSingleResult.getScanData());
1282d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, secondScanRequestId);
1283d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1284d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1285d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1286d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1287d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response2 = verifyHandleMessageAndGetMessage(order, handler);
1288d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1289d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results2 = Arrays.asList(
1290d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response2.obj).getResults());
1291d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results2.size(), expectedSingleResult.getRawScanResults().length);
1292d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1293d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1294d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
1295d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     * Cached scan results should be cleared after the driver is unloaded.
1296d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein     */
1297d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    @Test
1298d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void validateScanResultsClearedAfterDriverUnloaded() throws Exception {
1299d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        WifiScanner.ScanSettings requestSettings =
1300d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                createRequest(WifiScanner.WIFI_BAND_BOTH_WITH_DFS,
1301d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                              0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1302d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        ScanResults expectedResults = ScanResults.create(0, true, 2400, 5150, 5175);
1303d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        doSuccessfulSingleScan(requestSettings,
1304d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               computeSingleScanNativeSettings(requestSettings),
1305d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                               expectedResults);
1306d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Handler handler = mock(Handler.class);
1307d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1308d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        InOrder order = inOrder(handler, mWifiScannerImpl);
1309d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1310d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1311d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1312d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1313d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response = verifyHandleMessageAndGetMessage(order, handler);
1314d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results = Arrays.asList(
1315d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response.obj).getResults());
1316d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results.size(), expectedResults.getRawScanResults().length);
1317d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1318d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // disable wifi
1319d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        TestUtil.sendWifiScanAvailable(mBroadcastReceiver,
1320d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                                       mContext,
1321d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                                       WifiManager.WIFI_STATE_DISABLED);
1322d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // Now get scan results again. The returned list should be empty since we
1323d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        // clear the cache when exiting the DriverLoaded state.
1324d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        controlChannel.sendMessage(
1325d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
1326d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        mLooper.dispatchAll();
1327d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        Message response2 = verifyHandleMessageAndGetMessage(order, handler);
1328d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        List<ScanResult> results2 = Arrays.asList(
1329d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein                ((WifiScanner.ParcelableScanResults) response2.obj).getResults());
1330d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        assertEquals(results2.size(), 0);
1331d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    }
1332d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein
1333d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    /**
13341ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Register a single scan listener and do a single scan
13351ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
13361ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
13371ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    public void registerScanListener() throws Exception {
13381ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
13391ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
13401ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanSettings nativeSettings = computeSingleScanNativeSettings(requestSettings);
13411ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results = ScanResults.create(0, 2400, 5150, 5175);
13421ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13431ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId = 12;
13441ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int listenerRequestId = 13;
13451ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13461ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
13471ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13481ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
13491ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
13501ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
13511ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13521ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
13531ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
13541ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13551ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        registerScanListener(controlChannel, listenerRequestId);
13561ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
13571ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, listenerRequestId);
13581ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13591ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
13601ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13611ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
13621ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings);
13631ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
13641ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13651ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
13661ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                .thenReturn(results.getRawScanData());
13671ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
13681ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13691ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
1370d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
1371d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId);
1372d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, listenerRequestId, results.getScanData());
13736c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
13741ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyNoMoreInteractions(handler);
13751ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13761ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsRequestLog("registerScanListener", listenerRequestId);
13771ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsCallbackLog("singleScanResults", listenerRequestId,
13781ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "results=" + results.getScanData().getResults().length);
13791ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
13801ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13811ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
13821ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Register a single scan listener and do a single scan
13831ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
13841ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
13851ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    public void deregisterScanListener() throws Exception {
13861ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
13871ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
13881ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanSettings nativeSettings = computeSingleScanNativeSettings(requestSettings);
13891ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results = ScanResults.create(0, 2400, 5150, 5175);
13901ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13911ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId = 12;
13921ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int listenerRequestId = 13;
13931ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13941ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
13951ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
13961ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
13971ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
13981ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
13991ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14001ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
14011ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
14021ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14031ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        registerScanListener(controlChannel, listenerRequestId);
14041ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
14051ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, listenerRequestId);
14061ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14071ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
14081ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14091ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
14101ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings);
14111ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(order, handler, requestId);
14121ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14131ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        deregisterScanListener(controlChannel, listenerRequestId);
14141ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
14151ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14161ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
14171ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                .thenReturn(results.getRawScanData());
14181ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
14191ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14201ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
1421d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
1422d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(order, handler, requestId);
14236c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
14241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyNoMoreInteractions(handler);
14251ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14261ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsRequestLog("registerScanListener", listenerRequestId);
14271ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsRequestLog("deregisterScanListener", listenerRequestId);
14281ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
14291ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14301ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    /**
14311ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * Send a single scan request and then two more before the first completes. Neither are
14321ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     * satisfied by the first scan. Verify that the first completes and the second two are merged.
14331ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills     */
14341ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    @Test
1435d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    public void scanListenerReceivesAllResults() throws RemoteException {
14361ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0,
14371ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
14381ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId1 = 12;
14391ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results1 = ScanResults.create(0, 2400);
14401ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14411ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
14421ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
14431ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId2 = 13;
14441ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450);
14451ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14461ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(5150), 0,
14471ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
14481ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int requestId3 = 15;
14491ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results3 = ScanResults.create(0, 5150, 5150, 5150, 5150);
14501ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14511ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanSettings nativeSettings2and3 = createSingleScanNativeSettingsForChannels(
14521ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channelsToSpec(2450, 5175, 5150));
14531ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        ScanResults results2and3 = ScanResults.merge(results2, results3);
14541ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14551ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        int listenerRequestId = 13;
14561ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14571ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14581ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        startServiceAndLoadDriver();
14591ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14601ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
14611ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
14621ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14631ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        Handler handler = mock(Handler.class);
14641ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
14651ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder handlerOrder = inOrder(handler);
14661ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        InOrder nativeOrder = inOrder(mWifiScannerImpl);
14671ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14681ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Run scan 1
14691ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
14701ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14711ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
14721ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
14731ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                computeSingleScanNativeSettings(requestSettings1));
14741ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId1);
14751ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14761ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14771ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Queue scan 2 (will not run because previous is in progress)
14781ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
14791ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
14801ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId2);
14811ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14821ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Queue scan 3 (will not run because previous is in progress)
14831ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        sendSingleScanRequest(controlChannel, requestId3, requestSettings3, null);
14841ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
14851ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, requestId3);
14861ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14871ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // Register scan listener
14881ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        registerScanListener(controlChannel, listenerRequestId);
14891ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
14901ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifySuccessfulResponse(handlerOrder, handler, listenerRequestId);
14911ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14921ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // dispatch scan 1 results
14931ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
14941ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                .thenReturn(results1.getScanData());
14951ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
14961ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
14971ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
1498d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, requestId1, results1.getScanData());
1499d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifySingleScanCompletedReceived(handlerOrder, handler, requestId1);
1500d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyScanResultsReceived(handlerOrder, handler, listenerRequestId, results1.getScanData());
15016c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein        verify(mContext).sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
15021ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15031ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // now that the first scan completed we expect the second and third ones to start
15041ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        WifiNative.ScanEventHandler eventHandler2and3 = verifyStartSingleScan(nativeOrder,
15051ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                nativeSettings2and3);
15061ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15071ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        // dispatch scan 2 and 3 results
15081ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
15091ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                .thenReturn(results2and3.getScanData());
15101ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
15111ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15121ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        mLooper.dispatchAll();
15131ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15141ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        verifyMultipleSingleScanResults(handlerOrder, handler, requestId2, results2, requestId3,
15151ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                results3, listenerRequestId, results2and3);
15161ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15171ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsRequestLog("registerScanListener", listenerRequestId);
15181ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsCallbackLog("singleScanResults", listenerRequestId,
15191ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "results=" + results1.getRawScanResults().length);
15201ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills        assertDumpContainsCallbackLog("singleScanResults", listenerRequestId,
15211ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills                "results=" + results2and3.getRawScanResults().length);
15221ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
15231ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
15258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    private void doSuccessfulBackgroundScan(WifiScanner.ScanSettings requestSettings,
15268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills            WifiNative.ScanSettings nativeSettings) {
15278adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        startServiceAndLoadDriver();
15288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
15298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        Handler handler = mock(Handler.class);
15308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
15318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        InOrder order = inOrder(handler, mWifiScannerImpl);
15328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
15338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
15348adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
15358adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
15360ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills        sendBackgroundScanRequest(controlChannel, 12, requestSettings, null);
15378adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        mLooper.dispatchAll();
15388adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyStartBackgroundScan(order, nativeSettings);
15398adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifySuccessfulResponse(order, handler, 12);
15408adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        verifyNoMoreInteractions(handler);
154159298c7cfffdf856e32879ec967fe27c7e977a49Mitchell Wills        assertDumpContainsRequestLog("addBackgroundScanRequest", 12);
15428adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
15438adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
15448adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
15458adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a background scan for a band and verify that it is successful.
15468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
15478adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
15488adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendBackgroundScanBandRequest() throws Exception {
1549e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 30000,
15508adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
15518adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder()
1552e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .withBasePeriod(30000)
15538adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withMaxApPerScan(MAX_AP_PER_SCAN)
155495984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills                .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH)
1555e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .addBucketWithBand(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
15568adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                        WifiScanner.WIFI_BAND_BOTH)
15578adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .build();
15588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        doSuccessfulBackgroundScan(requestSettings, nativeSettings);
1559c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        assertEquals(mWifiMetrics.getBackgroundScanCount(), 1);
15608adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
15618adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
15628adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    /**
15638adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     * Do a background scan for a list of channels and verify that it is successful.
15648adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills     */
15658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    @Test
15668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    public void sendBackgroundScanChannelsRequest() throws Exception {
1567e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(5150), 30000,
15688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
15698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder()
1570e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .withBasePeriod(30000)
15718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .withMaxApPerScan(MAX_AP_PER_SCAN)
157295984d1af44a00183a4b0e0ed61417583096ff90Mitchell Wills                .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH)
1573e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .addBucketWithChannels(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5150)
15748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills                .build();
15758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        doSuccessfulBackgroundScan(requestSettings, nativeSettings);
15768adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
1577c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1578c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> createScanSettingsForHwPno()
1579c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            throws Exception {
1580c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiScanner.ScanSettings requestSettings = createRequest(
1581e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                channelsToSpec(0, 2400, 5150, 5175), 30000, 0, 20,
1582c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1583c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder()
1584e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .withBasePeriod(30000)
1585c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                .withMaxApPerScan(MAX_AP_PER_SCAN)
1586c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                .withMaxScansToCache(BackgroundScanScheduler.DEFAULT_MAX_SCANS_TO_BATCH)
1587e733ddab5260b153ad76ed73a672de928d0f4b37Mitchell Wills                .addBucketWithChannels(30000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
1588c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                        0, 2400, 5150, 5175)
1589c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                .build();
1590c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return Pair.create(requestSettings, nativeSettings);
1591c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1592c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1593c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> createScanSettingsForSwPno()
1594c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            throws Exception {
1595c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> settingsPair =
1596c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForHwPno();
1597c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1598c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiScanner.ScanSettings requestSettings = settingsPair.first;
1599c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.ScanSettings nativeSettings = settingsPair.second;
1600c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        // reportEvents field is overridden for SW PNO
1601c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        for (int i = 0; i < nativeSettings.buckets.length; i++) {
1602c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativeSettings.buckets[i].report_events = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
1603c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                    | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT;
1604c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        }
1605c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return Pair.create(requestSettings, nativeSettings);
1606c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1607c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1608c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> createPnoSettings(
1609c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            ScanResults results)
1610c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            throws Exception {
1611c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiScanner.PnoSettings requestPnoSettings = new WifiScanner.PnoSettings();
1612c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        requestPnoSettings.networkList =
1613c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                new WifiScanner.PnoSettings.PnoNetwork[results.getRawScanResults().length];
1614c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int i = 0;
1615c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        for (ScanResult scanResult : results.getRawScanResults()) {
1616c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            requestPnoSettings.networkList[i++] =
1617c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                    new WifiScanner.PnoSettings.PnoNetwork(scanResult.SSID);
1618c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        }
1619c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1620c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.PnoSettings nativePnoSettings = new WifiNative.PnoSettings();
1621c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.min5GHzRssi = requestPnoSettings.min5GHzRssi;
1622c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.min24GHzRssi = requestPnoSettings.min24GHzRssi;
1623c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.initialScoreMax = requestPnoSettings.initialScoreMax;
1624c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.currentConnectionBonus = requestPnoSettings.currentConnectionBonus;
1625c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.sameNetworkBonus = requestPnoSettings.sameNetworkBonus;
1626c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.secureBonus = requestPnoSettings.secureBonus;
1627c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.band5GHzBonus = requestPnoSettings.band5GHzBonus;
1628c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.isConnected = requestPnoSettings.isConnected;
1629c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        nativePnoSettings.networkList =
1630c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                new WifiNative.PnoNetwork[requestPnoSettings.networkList.length];
1631c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        for (i = 0; i < requestPnoSettings.networkList.length; i++) {
1632c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativePnoSettings.networkList[i] = new WifiNative.PnoNetwork();
1633c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativePnoSettings.networkList[i].ssid = requestPnoSettings.networkList[i].ssid;
1634c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativePnoSettings.networkList[i].flags = requestPnoSettings.networkList[i].flags;
1635c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            nativePnoSettings.networkList[i].auth_bit_field =
1636c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                    requestPnoSettings.networkList[i].authBitField;
1637c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        }
1638c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return Pair.create(requestPnoSettings, nativePnoSettings);
1639c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1640c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1641c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private ScanResults createScanResultsForPno() {
1642c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return ScanResults.create(0, 2400, 5150, 5175);
1643c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1644c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1645c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private ScanResults createScanResultsForPnoWithNoIE() {
1646c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return ScanResults.createWithNoIE(0, 2400, 5150, 5175);
1647c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1648c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1649c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private WifiNative.PnoEventHandler verifyHwPno(InOrder order,
1650c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.PnoSettings expected) {
1651c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ArgumentCaptor<WifiNative.PnoSettings> pnoSettingsCaptor =
1652c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                ArgumentCaptor.forClass(WifiNative.PnoSettings.class);
1653c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ArgumentCaptor<WifiNative.PnoEventHandler> pnoEventHandlerCaptor =
1654c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                ArgumentCaptor.forClass(WifiNative.PnoEventHandler.class);
1655c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        order.verify(mWifiScannerImpl).setHwPnoList(pnoSettingsCaptor.capture(),
1656c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                pnoEventHandlerCaptor.capture());
1657c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        assertNativePnoSettingsEquals(expected, pnoSettingsCaptor.getValue());
1658c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        return pnoEventHandlerCaptor.getValue();
1659c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1660c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1661c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void sendPnoScanRequest(BidirectionalAsyncChannel controlChannel,
1662c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            int scanRequestId, WifiScanner.ScanSettings scanSettings,
1663c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiScanner.PnoSettings pnoSettings) {
1664c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Bundle pnoParams = new Bundle();
1665c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        scanSettings.isPnoScan = true;
1666c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        pnoParams.putParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY, scanSettings);
1667c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        pnoParams.putParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY, pnoSettings);
1668c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_PNO_SCAN, 0,
1669c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                scanRequestId, pnoParams));
1670c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1671c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1672c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void assertPnoNetworkFoundMessage(int listenerId, ScanResult[] expected,
1673c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            Message networkFoundMessage) {
1674c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        assertEquals("what", WifiScanner.CMD_PNO_NETWORK_FOUND, networkFoundMessage.what);
1675c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        assertEquals("listenerId", listenerId, networkFoundMessage.arg2);
1676a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills        assertScanResultsEquals(expected,
1677c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                ((WifiScanner.ParcelableScanResults) networkFoundMessage.obj).getResults());
1678c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1679c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1680d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein    private void verifyPnoNetworkFoundReceived(InOrder order, Handler handler, int listenerId,
1681c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            ScanResult[] expected) {
1682c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler,
1683c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                WifiScanner.CMD_PNO_NETWORK_FOUND);
1684c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        assertPnoNetworkFoundMessage(listenerId, expected, scanResultMessage);
1685c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1686c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1687c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectSuccessfulBackgroundScan(InOrder order,
1688c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.ScanSettings nativeSettings, ScanResults results) {
1689c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
1690c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.ScanEventHandler.class))).thenReturn(true);
1691c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1692c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.ScanEventHandler eventHandler = verifyStartBackgroundScan(order, nativeSettings);
1693c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiScanner.ScanData[] scanDatas = new WifiScanner.ScanData[1];
1694c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        scanDatas[0] = results.getScanData();
1695c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        for (ScanResult fullScanResult : results.getRawScanResults()) {
1696c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            eventHandler.onFullScanResult(fullScanResult, 0);
1697c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        }
1698c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.getLatestBatchedScanResults(anyBoolean())).thenReturn(scanDatas);
1699c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
1700c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1701c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1702c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1703c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectHwPnoScanWithNoBackgroundScan(InOrder order, Handler handler, int requestId,
1704c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.PnoSettings nativeSettings, ScanResults results) {
1705c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(true);
1706c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(false);
1707c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1708c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.setHwPnoList(any(WifiNative.PnoSettings.class),
1709c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.PnoEventHandler.class))).thenReturn(true);
1710c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1711c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.PnoEventHandler eventHandler = verifyHwPno(order, nativeSettings);
1712c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        verifySuccessfulResponse(order, handler, requestId);
1713c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        eventHandler.onPnoNetworkFound(results.getRawScanResults());
1714c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1715c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1716c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1717c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectHwPnoScanWithBackgroundScan(InOrder order, Handler handler, int requestId,
1718c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.ScanSettings nativeScanSettings,
1719c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.PnoSettings nativePnoSettings, ScanResults results) {
1720c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(true);
1721c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(true);
1722c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1723c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.setHwPnoList(any(WifiNative.PnoSettings.class),
1724c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.PnoEventHandler.class))).thenReturn(true);
1725c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
1726c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.ScanEventHandler.class))).thenReturn(true);
1727c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1728c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.PnoEventHandler eventHandler = verifyHwPno(order, nativePnoSettings);
1729c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        verifySuccessfulResponse(order, handler, requestId);
1730c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        verifyStartBackgroundScan(order, nativeScanSettings);
1731c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        eventHandler.onPnoNetworkFound(results.getRawScanResults());
1732c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1733c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1734c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1735c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectHwPnoScanWithBackgroundScanWithNoIE(InOrder order, Handler handler,
1736c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            int requestId, WifiNative.ScanSettings nativeBackgroundScanSettings,
1737c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.ScanSettings nativeSingleScanSettings,
1738c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            WifiNative.PnoSettings nativePnoSettings, ScanResults results) {
1739c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
1740c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                any(WifiNative.ScanEventHandler.class))).thenReturn(true);
1741c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1742c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectHwPnoScanWithBackgroundScan(order, handler, requestId, nativeBackgroundScanSettings,
1743c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                nativePnoSettings, results);
1744c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        WifiNative.ScanEventHandler eventHandler =
1745c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                verifyStartSingleScan(order, nativeSingleScanSettings);
1746c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.getLatestSingleScanResults()).thenReturn(results.getScanData());
1747c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
1748c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        mLooper.dispatchAll();
1749c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1750c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    private void expectSwPnoScan(InOrder order, WifiNative.ScanSettings nativeScanSettings,
1751c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius            ScanResults results) {
1752c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(false);
1753c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        when(mWifiScannerImpl.shouldScheduleBackgroundScanForHwPno()).thenReturn(true);
1754c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1755c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectSuccessfulBackgroundScan(order, nativeScanSettings, results);
1756c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1757c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1758c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    /**
1759c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * Tests Supplicant PNO scan when the PNO scan results contain IE info. This ensures that the
1760c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * PNO scan results are plumbed back to the client as a PNO network found event.
1761c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     */
1762c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    @Test
1763c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    public void testSuccessfulHwPnoScanWithNoBackgroundScan() throws Exception {
1764c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        startServiceAndLoadDriver();
1765c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Handler handler = mock(Handler.class);
1766c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1767c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
1768c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int requestId = 12;
1769c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1770c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ScanResults scanResults = createScanResultsForPno();
1771c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
1772c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForHwPno();
1773c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
1774c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createPnoSettings(scanResults);
1775c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1776c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
1777c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectHwPnoScanWithNoBackgroundScan(order, handler, requestId, pnoSettings.second,
1778c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                scanResults);
1779d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults());
1780c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1781c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1782c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    /**
1783c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * Tests Hal ePNO scan when the PNO scan results contain IE info. This ensures that the
1784c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * PNO scan results are plumbed back to the client as a PNO network found event.
1785c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     */
1786c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    @Test
1787c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    public void testSuccessfulHwPnoScanWithBackgroundScan() throws Exception {
1788c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        startServiceAndLoadDriver();
1789c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Handler handler = mock(Handler.class);
1790c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1791c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
1792c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int requestId = 12;
1793c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1794c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ScanResults scanResults = createScanResultsForPno();
1795c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
1796c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForHwPno();
1797c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
1798c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createPnoSettings(scanResults);
1799c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1800c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
1801c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectHwPnoScanWithBackgroundScan(order, handler, requestId, scanSettings.second,
1802c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                pnoSettings.second, scanResults);
1803d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults());
1804c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1805c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1806c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    /**
1807c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * Tests Hal ePNO scan when the PNO scan results don't contain IE info. This ensures that the
1808c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * single scan results are plumbed back to the client as a PNO network found event.
1809c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     */
1810c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    @Test
1811c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    public void testSuccessfulHwPnoScanWithBackgroundScanWithNoIE() throws Exception {
1812c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        startServiceAndLoadDriver();
1813c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Handler handler = mock(Handler.class);
1814c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1815c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
1816c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int requestId = 12;
1817c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1818c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ScanResults scanResults = createScanResultsForPnoWithNoIE();
1819c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
1820c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForHwPno();
1821c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
1822c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createPnoSettings(scanResults);
1823c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1824c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
1825c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectHwPnoScanWithBackgroundScanWithNoIE(order, handler, requestId, scanSettings.second,
1826c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                computeSingleScanNativeSettings(scanSettings.first), pnoSettings.second,
1827c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                scanResults);
1828c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1829c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ArrayList<ScanResult> sortScanList =
1830c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                new ArrayList<ScanResult>(Arrays.asList(scanResults.getRawScanResults()));
1831c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Collections.sort(sortScanList, WifiScannerImpl.SCAN_RESULT_SORT_COMPARATOR);
1832d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyPnoNetworkFoundReceived(order, handler, requestId,
1833c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                sortScanList.toArray(new ScanResult[sortScanList.size()]));
1834c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
1835c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1836c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    /**
1837c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * Tests SW PNO scan. This ensures that the background scan results are plumbed back to the
1838c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     * client as a PNO network found event.
1839c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius     */
1840c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    @Test
1841c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    public void testSuccessfulSwPnoScan() throws Exception {
1842c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        startServiceAndLoadDriver();
1843c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Handler handler = mock(Handler.class);
1844c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1845c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        InOrder order = inOrder(handler, mWifiScannerImpl);
1846c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        int requestId = 12;
1847c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1848c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        ScanResults scanResults = createScanResultsForPno();
1849c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
1850c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createScanSettingsForSwPno();
1851c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
1852c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius                createPnoSettings(scanResults);
1853c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
1854c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
1855c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        expectSwPnoScan(order, scanSettings.second, scanResults);
1856d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein        verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults());
1857c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
18585382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
18595382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius    /**
18605382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius     * Tries to simulate the race scenario where a client is disconnected immediately after single
18615382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius     * scan request is sent to |SingleScanStateMachine|.
18625382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius     */
18635382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius    @Test
18645382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius    public void processSingleScanRequestAfterDisconnect() throws Exception {
18655382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        startServiceAndLoadDriver();
18665382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        BidirectionalAsyncChannel controlChannel = connectChannel(mock(Handler.class));
18675382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        mLooper.dispatchAll();
18685382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
18695382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // Send the single scan request and then send the disconnect immediately after.
18705382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
18715382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
18725382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        int requestId = 10;
18735382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
18745382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
18755382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // Can't call |disconnect| here because that sends |CMD_CHANNEL_DISCONNECT| followed by
18765382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // |CMD_CHANNEL_DISCONNECTED|.
1877c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        controlChannel.sendMessage(Message.obtain(null, AsyncChannel.CMD_CHANNEL_DISCONNECTED,
1878c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                        AsyncChannel.STATUS_REMOTE_DISCONNECTION, 0, null));
18795382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
18805382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // Now process the above 2 actions. This should result in first processing the single scan
18815382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // request (which forwards the request to SingleScanStateMachine) and then processing the
18825382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // disconnect after.
18835382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        mLooper.dispatchAll();
18845382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
18855382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        // Now check that we logged the invalid request.
18865382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        String serviceDump = dumpService();
18875382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        Pattern logLineRegex = Pattern.compile("^.+" + "singleScanInvalidRequest: "
18885382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius                + "ClientInfo\\[unknown\\],Id=" + requestId + ",bad request$", Pattern.MULTILINE);
18895382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius        assertTrue("dump did not contain log with ClientInfo[unknown]: " + serviceDump + "\n",
18905382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius                logLineRegex.matcher(serviceDump).find());
18915382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius    }
18925382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius
1893c9c91fd93350151a33d87fca768921520c256256Mitchell Wills    /**
1894c9c91fd93350151a33d87fca768921520c256256Mitchell Wills     * Tries to simulate the race scenario where a client is disconnected immediately after single
1895c9c91fd93350151a33d87fca768921520c256256Mitchell Wills     * scan request is sent to |SingleScanStateMachine|.
1896c9c91fd93350151a33d87fca768921520c256256Mitchell Wills     */
1897c9c91fd93350151a33d87fca768921520c256256Mitchell Wills    @Test
1898c9c91fd93350151a33d87fca768921520c256256Mitchell Wills    public void sendScanRequestAfterUnsuccessfulSend() throws Exception {
1899c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
1900c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
1901c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        int requestId = 9;
1902c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
1903c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        startServiceAndLoadDriver();
1904c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        Handler handler = mock(Handler.class);
1905c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        BidirectionalAsyncChannel controlChannel = connectChannel(handler);
1906c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
1907c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
1908c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
1909c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                        any(WifiNative.ScanEventHandler.class))).thenReturn(true);
1910c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        ScanResults results = ScanResults.create(0, 2400);
1911c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        when(mWifiScannerImpl.getLatestSingleScanResults())
1912c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                .thenReturn(results.getRawScanData());
1913c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
1914c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        InOrder order = inOrder(mWifiScannerImpl, handler);
1915c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
1916c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
1917c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
1918c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(order,
1919c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                computeSingleScanNativeSettings(requestSettings));
1920c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifySuccessfulResponse(order, handler, requestId);
1921c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
1922c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
1923c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
1924c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
1925c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifySingleScanCompletedReceived(order, handler, requestId);
1926c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifyNoMoreInteractions(handler);
1927c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
1928c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        controlChannel.sendMessage(Message.obtain(null, AsyncChannel.CMD_CHANNEL_DISCONNECTED,
1929c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                        AsyncChannel.STATUS_SEND_UNSUCCESSFUL, 0, null));
1930c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
1931c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
1932c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
1933c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
1934c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(order,
1935c9c91fd93350151a33d87fca768921520c256256Mitchell Wills                computeSingleScanNativeSettings(requestSettings));
1936c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifySuccessfulResponse(order, handler, requestId);
1937c9c91fd93350151a33d87fca768921520c256256Mitchell Wills
1938c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
1939c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        mLooper.dispatchAll();
1940c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifyScanResultsReceived(order, handler, requestId, results.getScanData());
1941c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifySingleScanCompletedReceived(order, handler, requestId);
1942c9c91fd93350151a33d87fca768921520c256256Mitchell Wills        verifyNoMoreInteractions(handler);
1943c9c91fd93350151a33d87fca768921520c256256Mitchell Wills    }
194494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills}
1945