Home | History | Annotate | Download | only in scanner
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.wifi.scanner;
     18 
     19 import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder;
     20 import static com.android.server.wifi.ScanTestUtil.setupMockChannels;
     21 
     22 import static org.junit.Assert.*;
     23 import static org.mockito.Mockito.*;
     24 
     25 import android.app.test.TestAlarmManager;
     26 import android.content.Context;
     27 import android.net.wifi.WifiScanner;
     28 import android.os.SystemClock;
     29 import android.os.test.TestLooper;
     30 import android.support.test.filters.SmallTest;
     31 
     32 import com.android.internal.R;
     33 import com.android.server.wifi.Clock;
     34 import com.android.server.wifi.MockResources;
     35 import com.android.server.wifi.MockWifiMonitor;
     36 import com.android.server.wifi.ScanResults;
     37 import com.android.server.wifi.WifiMonitor;
     38 import com.android.server.wifi.WifiNative;
     39 import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection;
     40 
     41 import org.junit.Before;
     42 import org.junit.Test;
     43 import org.mockito.InOrder;
     44 import org.mockito.Mock;
     45 import org.mockito.MockitoAnnotations;
     46 
     47 import java.util.Set;
     48 
     49 /**
     50  * Unit tests for {@link com.android.server.wifi.scanner.WificondScannerImpl.setPnoList}.
     51  */
     52 @SmallTest
     53 public class WificondPnoScannerTest {
     54     private static final String IFACE_NAME = "a_test_interface_name";
     55 
     56     @Mock Context mContext;
     57     TestAlarmManager mAlarmManager;
     58     MockWifiMonitor mWifiMonitor;
     59     TestLooper mLooper;
     60     @Mock WifiNative mWifiNative;
     61     MockResources mResources;
     62     @Mock Clock mClock;
     63     WificondScannerImpl mScanner;
     64 
     65     @Before
     66     public void setup() throws Exception {
     67         MockitoAnnotations.initMocks(this);
     68 
     69         mLooper = new TestLooper();
     70         mAlarmManager = new TestAlarmManager();
     71         mWifiMonitor = new MockWifiMonitor();
     72         mResources = new MockResources();
     73 
     74         setupMockChannels(mWifiNative,
     75                 new int[]{2400, 2450},
     76                 new int[]{5150, 5175},
     77                 new int[]{5600, 5650});
     78 
     79         when(mWifiNative.getClientInterfaceName()).thenReturn(IFACE_NAME);
     80         when(mContext.getSystemService(Context.ALARM_SERVICE))
     81                 .thenReturn(mAlarmManager.getAlarmManager());
     82         when(mContext.getResources()).thenReturn(mResources);
     83         when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
     84     }
     85 
     86     /**
     87      * Verify that the HW disconnected PNO scan triggers a wificond PNO scan and invokes the
     88      * OnPnoNetworkFound callback when the scan results are received.
     89      */
     90     @Test
     91     public void startHwDisconnectedPnoScan() {
     92         createScannerWithHwPnoScanSupport();
     93 
     94         WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
     95         WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(false);
     96         ScanResults scanResults = createDummyScanResults(false);
     97 
     98         InOrder order = inOrder(pnoEventHandler, mWifiNative);
     99         // Start PNO scan
    100         startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
    101         expectSuccessfulHwDisconnectedPnoScan(order, pnoSettings, pnoEventHandler, scanResults);
    102         verifyNoMoreInteractions(pnoEventHandler);
    103     }
    104 
    105     /**
    106      * Verify that the HW PNO scan stop failure still resets the PNO scan state.
    107      * 1. Start Hw PNO.
    108      * 2. Stop Hw PNO scan which raises a stop command to WifiNative which is failed.
    109      * 3. Now restart a new PNO scan to ensure that the failure was cleanly handled.
    110      */
    111     @Test
    112     public void ignoreHwDisconnectedPnoScanStopFailure() {
    113         createScannerWithHwPnoScanSupport();
    114 
    115         WifiNative.PnoEventHandler pnoEventHandler = mock(WifiNative.PnoEventHandler.class);
    116         WifiNative.PnoSettings pnoSettings = createDummyPnoSettings(false);
    117 
    118         // Start PNO scan
    119         startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
    120 
    121         // Fail the PNO stop.
    122         when(mWifiNative.stopPnoScan(IFACE_NAME)).thenReturn(false);
    123         assertTrue(mScanner.resetHwPnoList());
    124         mLooper.dispatchAll();
    125         verify(mWifiNative).stopPnoScan(IFACE_NAME);
    126 
    127         // Add a new PNO scan request and ensure it runs successfully.
    128         startSuccessfulPnoScan(null, pnoSettings, null, pnoEventHandler);
    129         mLooper.dispatchAll();
    130         InOrder order = inOrder(pnoEventHandler, mWifiNative);
    131         ScanResults scanResults = createDummyScanResults(false);
    132         expectSuccessfulHwDisconnectedPnoScan(order, pnoSettings, pnoEventHandler, scanResults);
    133         verifyNoMoreInteractions(pnoEventHandler);
    134     }
    135 
    136     private void createScannerWithHwPnoScanSupport() {
    137         mResources.setBoolean(R.bool.config_wifi_background_scan_support, true);
    138         mScanner = new WificondScannerImpl(mContext, IFACE_NAME, mWifiNative, mWifiMonitor,
    139                 new WificondChannelHelper(mWifiNative), mLooper.getLooper(), mClock);
    140     }
    141 
    142     private WifiNative.PnoNetwork createDummyPnoNetwork(String ssid) {
    143         WifiNative.PnoNetwork pnoNetwork = new WifiNative.PnoNetwork();
    144         pnoNetwork.ssid = ssid;
    145         return pnoNetwork;
    146     }
    147 
    148     private WifiNative.PnoSettings createDummyPnoSettings(boolean isConnected) {
    149         WifiNative.PnoSettings pnoSettings = new WifiNative.PnoSettings();
    150         pnoSettings.isConnected = isConnected;
    151         pnoSettings.networkList = new WifiNative.PnoNetwork[2];
    152         pnoSettings.networkList[0] = createDummyPnoNetwork("ssid_pno_1");
    153         pnoSettings.networkList[1] = createDummyPnoNetwork("ssid_pno_2");
    154         return pnoSettings;
    155     }
    156 
    157     private WifiNative.ScanSettings createDummyScanSettings(boolean allChannelsScanned) {
    158         WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
    159                 .withBasePeriod(10000)
    160                 .withMaxApPerScan(10)
    161                 .addBucketWithBand(
    162                     10000,
    163                     WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN,
    164                     allChannelsScanned
    165                             ? WifiScanner.WIFI_BAND_BOTH_WITH_DFS : WifiScanner.WIFI_BAND_24_GHZ)
    166                 .build();
    167         return settings;
    168     }
    169 
    170     private ScanResults createDummyScanResults(boolean allChannelsScanned) {
    171         return ScanResults.create(0, allChannelsScanned, 2400, 2450, 2450, 2400, 2450, 2450, 2400,
    172                 2450, 2450);
    173     }
    174 
    175     private void startSuccessfulPnoScan(WifiNative.ScanSettings scanSettings,
    176             WifiNative.PnoSettings pnoSettings, WifiNative.ScanEventHandler scanEventHandler,
    177             WifiNative.PnoEventHandler pnoEventHandler) {
    178         // Scans succeed
    179         when(mWifiNative.scan(eq(IFACE_NAME), anyInt(), any(), any(Set.class))).thenReturn(true);
    180         when(mWifiNative.startPnoScan(eq(IFACE_NAME), any(WifiNative.PnoSettings.class)))
    181                 .thenReturn(true);
    182         when(mWifiNative.stopPnoScan(IFACE_NAME)).thenReturn(true);
    183 
    184         assertTrue(mScanner.setHwPnoList(pnoSettings, pnoEventHandler));
    185     }
    186 
    187     private Set<Integer> expectedBandScanFreqs(int band) {
    188         ChannelCollection collection = mScanner.getChannelHelper().createChannelCollection();
    189         collection.addBand(band);
    190         return collection.getScanFreqs();
    191     }
    192 
    193     /**
    194      * Verify that the PNO scan was successfully started.
    195      */
    196     private void expectHwDisconnectedPnoScanStart(InOrder order,
    197             WifiNative.PnoSettings pnoSettings) {
    198         // Verify  HW PNO scan started
    199         order.verify(mWifiNative).startPnoScan(any(), any(WifiNative.PnoSettings.class));
    200     }
    201 
    202     /**
    203      *
    204      * 1. Verify that the PNO scan was successfully started.
    205      * 2. Send scan results and ensure that the |onPnoNetworkFound| callback was called.
    206      */
    207     private void expectSuccessfulHwDisconnectedPnoScan(InOrder order,
    208             WifiNative.PnoSettings pnoSettings, WifiNative.PnoEventHandler eventHandler,
    209             ScanResults scanResults) {
    210         expectHwDisconnectedPnoScanStart(order, pnoSettings);
    211 
    212         // Setup scan results
    213         when(mWifiNative.getPnoScanResults(IFACE_NAME))
    214                 .thenReturn(scanResults.getScanDetailArrayList());
    215         when(mWifiNative.getScanResults(IFACE_NAME))
    216                 .thenReturn(scanResults.getScanDetailArrayList());
    217 
    218         // Notify scan has finished
    219         mWifiMonitor.sendMessage(IFACE_NAME, WifiMonitor.PNO_SCAN_RESULTS_EVENT);
    220         assertEquals("dispatch message after results event", 1, mLooper.dispatchAll());
    221 
    222         order.verify(eventHandler).onPnoNetworkFound(scanResults.getRawScanResults());
    223     }
    224 
    225 }
    226