162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius/*
262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius * Copyright (C) 2016 The Android Open Source Project
362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius *
462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius * Licensed under the Apache License, Version 2.0 (the "License");
562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius * you may not use this file except in compliance with the License.
662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius * You may obtain a copy of the License at
762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius *
862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius *      http://www.apache.org/licenses/LICENSE-2.0
962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius *
1062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius * Unless required by applicable law or agreed to in writing, software
1162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius * distributed under the License is distributed on an "AS IS" BASIS,
1262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius * See the License for the specific language governing permissions and
14a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills * limitations under the License.
1562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius */
1662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
17a8367288377cbaed6371256ca837b7aa22280706Mitchell Willspackage com.android.server.wifi.scanner;
1862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
19e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Piusimport static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder;
20e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Piusimport static com.android.server.wifi.ScanTestUtil.assertScanDataEquals;
21e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius
22e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Piusimport static org.junit.Assert.*;
23e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Piusimport static org.mockito.Mockito.*;
24e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius
2562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport android.content.Context;
2662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport android.net.wifi.WifiConfiguration;
2762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport android.net.wifi.WifiScanner;
28ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Piusimport android.os.SystemClock;
2962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport android.test.suitebuilder.annotation.SmallTest;
3062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
3162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport com.android.internal.R;
32ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Piusimport com.android.server.wifi.Clock;
33a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.MockAlarmManager;
34a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.MockLooper;
35a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.MockResources;
36a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.MockWifiMonitor;
37a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.ScanResults;
38a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiMonitor;
39a8367288377cbaed6371256ca837b7aa22280706Mitchell Willsimport com.android.server.wifi.WifiNative;
4062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport com.android.server.wifi.scanner.ChannelHelper.ChannelCollection;
4162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
4262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport org.junit.Before;
4362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport org.junit.Test;
4462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport org.mockito.InOrder;
4562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport org.mockito.Mock;
4662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport org.mockito.MockitoAnnotations;
4762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
4862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport java.util.HashSet;
4962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport java.util.Set;
5062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
5162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
5262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius/**
53a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills * Unit tests for {@link com.android.server.wifi.scanner.SupplicantWifiScannerImpl.setPnoList}.
5462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius */
5562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius@SmallTest
5662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piuspublic class SupplicantPnoScannerTest {
5762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
5862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    @Mock Context mContext;
5962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    MockAlarmManager mAlarmManager;
6062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    MockWifiMonitor mWifiMonitor;
6162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    MockLooper mLooper;
6262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    @Mock WifiNative mWifiNative;
6362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    MockResources mResources;
64ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius    @Mock Clock mClock;
6562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    SupplicantWifiScannerImpl mScanner;
6662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
6762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    @Before
6862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    public void setup() throws Exception {
6962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        MockitoAnnotations.initMocks(this);
7062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
7162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        mLooper = new MockLooper();
7262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        mAlarmManager = new MockAlarmManager();
7362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        mWifiMonitor = new MockWifiMonitor();
7462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        mResources = new MockResources();
7562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
7662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        when(mWifiNative.getInterfaceName()).thenReturn("a_test_interface_name");
7762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        when(mContext.getSystemService(Context.ALARM_SERVICE))
7862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius                .thenReturn(mAlarmManager.getAlarmManager());
7962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        when(mContext.getResources()).thenReturn(mResources);
80ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime());
8162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
8262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
8362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    /**
846c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * Verify that the HW disconnected PNO scan triggers a supplicant PNO scan and invokes the
856c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * OnPnoNetworkFound callback when the scan results are received.
8662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius     */
8762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    @Test
88dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    public void startHwDisconnectedPnoScan() {
8962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        createScannerWithHwPnoScanSupport();
9062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
9162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
92dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(false);
9362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        ScanResults scanResults = createDummyScanResults();
9462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
9562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        InOrder order = inOrder(pnoEventHandler, mWifiNative);
9662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Start PNO scan
9762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
98dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        expectSuccessfulHwDisconnectedPnoScan(order, pnoSettings, pnoEventHandler, scanResults);
9962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        verifyNoMoreInteractions(pnoEventHandler);
10062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
10162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
10262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    /**
1036c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * Verify that we pause & resume HW PNO scan when a single scan is scheduled and invokes the
1046c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * OnPnoNetworkFound callback when the scan results are received.
10562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius     */
10662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    @Test
107dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    public void pauseResumeHwDisconnectedPnoScanForSingleScan() {
10862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        createScannerWithHwPnoScanSupport();
10962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
11062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
111dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(false);
11262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
11362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        WifiNative.ScanSettings settings = createDummyScanSettings();
11462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        ScanResults scanResults = createDummyScanResults();
11562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
11662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        InOrder order = inOrder(eventHandler, mWifiNative);
11762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Start PNO scan
11862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
11962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Start single scan
12062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        assertTrue(mScanner.startSingleScan(settings, eventHandler));
12162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Verify that the PNO scan was paused and single scan runs successfully
12262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        expectSuccessfulSingleScanWithHwPnoEnabled(order, eventHandler,
12362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius                expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ), new HashSet<Integer>(),
12462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius                scanResults);
12562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        verifyNoMoreInteractions(eventHandler);
12662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
12762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        order = inOrder(pnoEventHandler, mWifiNative);
128e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        // Resume PNO scan after the single scan results are received and PNO monitor debounce
129e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        // alarm fires.
130e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        assertTrue("dispatch pno monitor alarm",
131e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius                mAlarmManager.dispatch(
132e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius                        SupplicantWifiScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
133e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        assertEquals("dispatch message after alarm", 1, mLooper.dispatchAll());
13462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Now verify that PNO scan is resumed successfully
135dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        expectSuccessfulHwDisconnectedPnoScan(order, pnoSettings, pnoEventHandler, scanResults);
13662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        verifyNoMoreInteractions(pnoEventHandler);
13762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
13862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
13962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    /**
1406c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * Verify that the SW disconnected PNO scan triggers a background scan and invokes the
1416c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * background scan callbacks when scan results are received.
14262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius     */
14362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    @Test
144dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    public void startSwDisconnectedPnoScan() {
14562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        createScannerWithSwPnoScanSupport();
1466c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        doSuccessfulSwPnoScanTest(false);
147dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    }
148dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius
149dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    /**
1506c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * Verify that the HW connected PNO scan triggers a background scan and invokes the
1516c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * background scan callbacks when scan results are received.
152dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius     */
153dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    @Test
154dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    public void startHwConnectedPnoScan() {
155dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        createScannerWithHwPnoScanSupport();
1566c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        doSuccessfulSwPnoScanTest(true);
157dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    }
158dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius
159dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    /**
1606c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * Verify that the SW connected PNO scan triggers a background scan and invokes the
1616c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * background scan callbacks when scan results are received.
162dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius     */
163dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    @Test
164dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    public void startSwConnectedPnoScan() {
165dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        createScannerWithSwPnoScanSupport();
1666c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        doSuccessfulSwPnoScanTest(true);
1676c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius    }
168dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius
169e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius    /**
170e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius     * Verify that the HW PNO delayed failure cleans up the scan settings cleanly.
171e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius     * 1. Start Hw PNO.
172e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius     * 2. Start Single Scan which should pause PNO scan.
173e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius     * 3. Fail the PNO scan resume and verify that the OnPnoScanFailed callback is invoked.
174e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius     * 4. Now restart a new PNO scan to ensure that the failure was cleanly handled.
175e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius     */
176e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius    @Test
177e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius    public void delayedHwDisconnectedPnoScanFailure() {
178e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        createScannerWithHwPnoScanSupport();
179e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius
180e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
181e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(false);
182e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
183e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        WifiNative.ScanSettings settings = createDummyScanSettings();
184e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        ScanResults scanResults = createDummyScanResults();
185e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius
186e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        InOrder order = inOrder(eventHandler, mWifiNative);
187e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        // Start PNO scan
188e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
189e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        // Start single scan
190e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        assertTrue(mScanner.startSingleScan(settings, eventHandler));
191e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        // Verify that the PNO scan was paused and single scan runs successfully
192e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        expectSuccessfulSingleScanWithHwPnoEnabled(order, eventHandler,
193e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius                expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ), new HashSet<Integer>(),
194e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius                scanResults);
195e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        verifyNoMoreInteractions(eventHandler);
196e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius
197e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        // Fail the PNO resume and check that the OnPnoScanFailed callback is invoked.
198e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        order = inOrder(pnoEventHandler, mWifiNative);
199e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        when(mWifiNative.setPnoScan(true)).thenReturn(false);
200e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        assertTrue("dispatch pno monitor alarm",
201e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius                mAlarmManager.dispatch(
202e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius                        SupplicantWifiScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
203e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        assertEquals("dispatch message after alarm", 1, mLooper.dispatchAll());
204e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        order.verify(pnoEventHandler).onPnoScanFailed();
205e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        verifyNoMoreInteractions(pnoEventHandler);
206e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius
207e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        // Add a new PNO scan request
208e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
209e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        assertTrue("dispatch pno monitor alarm",
210e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius                mAlarmManager.dispatch(
211e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius                        SupplicantWifiScannerImpl.HwPnoDebouncer.PNO_DEBOUNCER_ALARM_TAG));
212e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        assertEquals("dispatch message after alarm", 1, mLooper.dispatchAll());
213e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        expectSuccessfulHwDisconnectedPnoScan(order, pnoSettings, pnoEventHandler, scanResults);
214e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        verifyNoMoreInteractions(pnoEventHandler);
215e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius    }
216e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius
2176c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius    private void doSuccessfulSwPnoScanTest(boolean isConnectedPno) {
218dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
2196c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(isConnectedPno);
22062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        WifiNative.ScanEventHandler scanEventHandler = mock(WifiNative.ScanEventHandler.class);
22162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        WifiNative.ScanSettings scanSettings = createDummyScanSettings();
22262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        ScanResults scanResults = createDummyScanResults();
22362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
2246c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        InOrder order = inOrder(scanEventHandler, mWifiNative);
22562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
22662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Start PNO scan
22762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        startSuccessfulPnoScan(scanSettings, pnoSettings, scanEventHandler, pnoEventHandler);
22862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
2296c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        expectSuccessfulSwPnoScan(order, scanEventHandler, scanResults);
23062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
23162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        verifyNoMoreInteractions(pnoEventHandler);
23262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
23362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
23462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    private void createScannerWithHwPnoScanSupport() {
23562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        mResources.setBoolean(R.bool.config_wifi_background_scan_support, true);
236ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius        mScanner =
237ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius                new SupplicantWifiScannerImpl(mContext, mWifiNative, mLooper.getLooper(), mClock);
23862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
23962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
24062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    private void createScannerWithSwPnoScanSupport() {
24162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        mResources.setBoolean(R.bool.config_wifi_background_scan_support, false);
242ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius        mScanner =
243ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius                new SupplicantWifiScannerImpl(mContext, mWifiNative, mLooper.getLooper(), mClock);
24462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
24562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
246dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    private WifiNative.PnoSettings createDummyPnoSettings(boolean isConnected) {
24762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        WifiNative.PnoSettings pnoSettings = new WifiNative.PnoSettings();
248dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        pnoSettings.isConnected = isConnected;
24962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        pnoSettings.networkList = new WifiNative.PnoNetwork[2];
25062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        pnoSettings.networkList[0] = new WifiNative.PnoNetwork();
25162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        pnoSettings.networkList[0].ssid = "ssid_pno_1";
25262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        pnoSettings.networkList[0].networkId = 1;
25362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        pnoSettings.networkList[0].priority = 1;
25462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        pnoSettings.networkList[1] = new WifiNative.PnoNetwork();
25562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        pnoSettings.networkList[1].ssid = "ssid_pno_2";
25662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        pnoSettings.networkList[1].networkId = 2;
25762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        pnoSettings.networkList[1].priority = 2;
25862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        return pnoSettings;
25962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
26062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
26162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    private WifiNative.ScanSettings createDummyScanSettings() {
26262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
26362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius                .withBasePeriod(10000)
26462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius                .withMaxApPerScan(10)
26562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius                .addBucketWithBand(10000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
26662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius                        WifiScanner.WIFI_BAND_24_GHZ)
26762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius                .build();
26862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        return settings;
26962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
27062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
27162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    private ScanResults createDummyScanResults() {
27262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        return ScanResults.create(0, 2400, 2450, 2450, 2400, 2450, 2450, 2400, 2450, 2450);
27362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
27462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
27562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    private void startSuccessfulPnoScan(WifiNative.ScanSettings scanSettings,
27662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius            WifiNative.PnoSettings pnoSettings, WifiNative.ScanEventHandler scanEventHandler,
27762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius            WifiNative.PnoEventHandler pnoEventHandler) {
27862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString())).thenReturn(true);
27962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        when(mWifiNative.enableNetworkWithoutConnect(anyInt())).thenReturn(true);
28062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Scans succeed
28162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        when(mWifiNative.scan(any(Set.class), any(Set.class))).thenReturn(true);
282e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        when(mWifiNative.setPnoScan(anyBoolean())).thenReturn(true);
2836c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius
284e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        if (mScanner.isHwPnoSupported(pnoSettings.isConnected)) {
285e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius            // This should happen only for HW PNO scan
286e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius            assertTrue(mScanner.setHwPnoList(pnoSettings, pnoEventHandler));
287e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        } else {
288e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius            // This should happen only for SW PNO scan
28962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius            assertTrue(mScanner.startBatchedScan(scanSettings, scanEventHandler));
290e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius
29162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        }
29262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
29362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
29462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    private Set<Integer> expectedBandScanFreqs(int band) {
29562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        ChannelCollection collection = mScanner.getChannelHelper().createChannelCollection();
29662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        collection.addBand(band);
29762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        return collection.getSupplicantScanFreqs();
29862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
29962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
30062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    /**
30162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius     * Verify that the PNO scan was successfully started.
30262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius     */
303dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius    private void expectSuccessfulHwDisconnectedPnoScan(InOrder order,
304dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius            WifiNative.PnoSettings pnoSettings, WifiNative.PnoEventHandler eventHandler,
305dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius            ScanResults scanResults) {
30662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        for (int i = 0; i < pnoSettings.networkList.length; i++) {
30762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius            WifiNative.PnoNetwork network = pnoSettings.networkList[i];
30862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius            order.verify(mWifiNative).setNetworkVariable(network.networkId,
30962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius                    WifiConfiguration.priorityVarName, Integer.toString(network.priority));
31062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius            order.verify(mWifiNative).enableNetworkWithoutConnect(network.networkId);
31162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        }
31262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Verify  HW PNO scan started
313e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        order.verify(mWifiNative).setPnoScan(true);
31462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
31562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Setup scan results
31662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        when(mWifiNative.getScanResults()).thenReturn(scanResults.getScanDetailArrayList());
31762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
31862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Notify scan has finished
31962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT);
32062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        assertEquals("dispatch message after results event", 1, mLooper.dispatchAll());
32162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
32262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        order.verify(eventHandler).onPnoNetworkFound(scanResults.getRawScanResults());
32362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
32462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
32562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    /**
32662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius     * Verify that the single scan results were delivered and that the PNO scan was paused and
32762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius     * resumed either side of it.
32862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius     */
32962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    private void expectSuccessfulSingleScanWithHwPnoEnabled(InOrder order,
33062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius            WifiNative.ScanEventHandler eventHandler, Set<Integer> expectedScanFreqs,
33162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius            Set<Integer> expectedHiddenNetIds, ScanResults scanResults) {
33262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Pause PNO scan first
333e7ba2963bedf426a1d8ba09ab535260ef364512bRoshan Pius        order.verify(mWifiNative).setPnoScan(false);
33462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
33562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        order.verify(mWifiNative).scan(eq(expectedScanFreqs), eq(expectedHiddenNetIds));
33662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
33762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        when(mWifiNative.getScanResults()).thenReturn(scanResults.getScanDetailArrayList());
33862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
33962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Notify scan has finished
34062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT);
34162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        assertEquals("dispatch message after results event", 1, mLooper.dispatchAll());
34262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
34362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
34462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        assertScanDataEquals(scanResults.getScanData(), mScanner.getLatestSingleScanResults());
34562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
34662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
34762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    /**
348dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius     * Verify that the SW PNO scan was successfully started. This could either be disconnected
349dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius     * or connected PNO.
3506c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * This is basically ensuring that the background scan runs successfully and returns the
3516c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius     * expected result.
35262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius     */
35362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    private void expectSuccessfulSwPnoScan(InOrder order,
3546c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius            WifiNative.ScanEventHandler eventHandler, ScanResults scanResults) {
35562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
35662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Verify scan started
35762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        order.verify(mWifiNative).scan(any(Set.class), any(Set.class));
35862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
35962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Make sure that HW PNO scan was not started
3608ba794562167643688ee38352f98345403fa22c8Roshan Pius        verify(mWifiNative, never()).setPnoScan(anyBoolean());
36162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
36262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Setup scan results
36362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        when(mWifiNative.getScanResults()).thenReturn(scanResults.getScanDetailArrayList());
36462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
36562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        // Notify scan has finished
36662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_RESULTS_EVENT);
36762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius        assertEquals("dispatch message after results event", 1, mLooper.dispatchAll());
36862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius
3696c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        // Verify background scan results delivered
3706c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
3716c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        WifiScanner.ScanData[] scanData = mScanner.getLatestBatchedScanResults(true);
3726c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        WifiScanner.ScanData lastScanData = scanData[scanData.length -1];
3736c5018cef1eb7acbcfa7fc6c9b7c018bab7ba7baRoshan Pius        assertScanDataEquals(scanResults.getScanData(), lastScanData);
37462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius    }
37562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius}
376