1e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu/*
2e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Copyright (C) 2016 The Android Open Source Project
3e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu *
4e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Licensed under the Apache License, Version 2.0 (the "License");
5e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * you may not use this file except in compliance with the License.
6e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * You may obtain a copy of the License at
7e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu *
8e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu *      http://www.apache.org/licenses/LICENSE-2.0
9e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu *
10e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Unless required by applicable law or agreed to in writing, software
11e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * distributed under the License is distributed on an "AS IS" BASIS,
12e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * See the License for the specific language governing permissions and
14e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * limitations under the License.
15e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu */
16e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
17e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiupackage com.android.server.wifi;
18e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
19e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport static org.mockito.Mockito.any;
20974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wileyimport static org.mockito.Mockito.anyBoolean;
21e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport static org.mockito.Mockito.anyInt;
22e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport static org.mockito.Mockito.eq;
23e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport static org.mockito.Mockito.inOrder;
24e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport static org.mockito.Mockito.never;
25e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport static org.mockito.Mockito.verify;
26e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport static org.mockito.Mockito.when;
27e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
28e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport android.net.InterfaceConfiguration;
29736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wileyimport android.net.wifi.IApInterface;
30e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport android.net.wifi.WifiConfiguration;
31e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport android.net.wifi.WifiManager;
32736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wileyimport android.os.IBinder;
33736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wileyimport android.os.IBinder.DeathRecipient;
34fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wileyimport android.os.INetworkManagementService;
35f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wileyimport android.os.test.TestLooper;
36e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport android.test.suitebuilder.annotation.SmallTest;
37e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
38fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wileyimport com.android.server.net.BaseNetworkObserver;
39fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley
40e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport org.junit.Before;
41e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport org.junit.Test;
42736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wileyimport org.mockito.ArgumentCaptor;
43e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport org.mockito.InOrder;
44e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport org.mockito.Mock;
45e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport org.mockito.MockitoAnnotations;
46e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
4779d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silbersteinimport java.nio.charset.StandardCharsets;
48e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport java.util.ArrayList;
49e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport java.util.Arrays;
50e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport java.util.Locale;
51e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
52be40e20f6995d9d11c8270502120a07785dde270Daniel Erat/** Unit tests for {@link SoftApManager}. */
53e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu@SmallTest
54e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiupublic class SoftApManagerTest {
55e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
56e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    private static final String TAG = "SoftApManagerTest";
57e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
5879d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    private static final String DEFAULT_SSID = "DefaultTestSSID";
59974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley    private static final String TEST_SSID = "TestSSID";
60e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    private static final String TEST_COUNTRY_CODE = "TestCountry";
61e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    private static final Integer[] ALLOWED_2G_CHANNELS = {1, 2, 3, 4};
62fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley    private static final String TEST_INTERFACE_NAME = "testif0";
63e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
64e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    private final ArrayList<Integer> mAllowed2GChannels =
65974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley            new ArrayList<>(Arrays.asList(ALLOWED_2G_CHANNELS));
66e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
6779d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    private final WifiConfiguration mDefaultApConfig = createDefaultApConfig();
6879d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein
69f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley    TestLooper mLooper;
70e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    @Mock WifiNative mWifiNative;
71e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    @Mock SoftApManager.Listener mListener;
72be40e20f6995d9d11c8270502120a07785dde270Daniel Erat    @Mock InterfaceConfiguration mInterfaceConfiguration;
73736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley    @Mock IBinder mApInterfaceBinder;
74974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley    @Mock IApInterface mApInterface;
75fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley    @Mock INetworkManagementService mNmService;
7679d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    @Mock WifiApConfigStore mWifiApConfigStore;
7780a1468c75b0db36e58de767c74f7c15e9aa55e3Rebecca Silberstein    @Mock WifiMetrics mWifiMetrics;
78736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley    final ArgumentCaptor<DeathRecipient> mDeathListenerCaptor =
79736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley            ArgumentCaptor.forClass(DeathRecipient.class);
80fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley    final ArgumentCaptor<BaseNetworkObserver> mNetworkObserverCaptor =
81fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley            ArgumentCaptor.forClass(BaseNetworkObserver.class);
82e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
83e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    SoftApManager mSoftApManager;
84e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
85be40e20f6995d9d11c8270502120a07785dde270Daniel Erat    /** Sets up test. */
86e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    @Before
87e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    public void setUp() throws Exception {
88e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        MockitoAnnotations.initMocks(this);
89f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley        mLooper = new TestLooper();
90e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
91736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley        when(mApInterface.asBinder()).thenReturn(mApInterfaceBinder);
92974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley        when(mApInterface.startHostapd()).thenReturn(true);
93974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley        when(mApInterface.stopHostapd()).thenReturn(true);
94974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley        when(mApInterface.writeHostapdConfig(
95974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley                any(), anyBoolean(), anyInt(), anyInt(), any())).thenReturn(true);
96fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley        when(mApInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME);
9779d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    }
98be40e20f6995d9d11c8270502120a07785dde270Daniel Erat
9979d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    private WifiConfiguration createDefaultApConfig() {
10079d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        WifiConfiguration defaultConfig = new WifiConfiguration();
10179d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        defaultConfig.SSID = DEFAULT_SSID;
10279d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        return defaultConfig;
10379d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    }
104e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
10579d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    private SoftApManager createSoftApManager(WifiConfiguration config) throws Exception {
10679d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        when(mApInterface.asBinder()).thenReturn(mApInterfaceBinder);
10779d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        when(mApInterface.startHostapd()).thenReturn(true);
10879d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        when(mApInterface.stopHostapd()).thenReturn(true);
1094e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein        if (config == null) {
1104e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein            when(mWifiApConfigStore.getApConfiguration()).thenReturn(mDefaultApConfig);
1114e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein        }
11279d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        SoftApManager newSoftApManager = new SoftApManager(mLooper.getLooper(),
11379d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein                                                           mWifiNative,
11479d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein                                                           TEST_COUNTRY_CODE,
11579d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein                                                           mListener,
11679d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein                                                           mApInterface,
11779d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein                                                           mNmService,
11879d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein                                                           mWifiApConfigStore,
11980a1468c75b0db36e58de767c74f7c15e9aa55e3Rebecca Silberstein                                                           config,
12080a1468c75b0db36e58de767c74f7c15e9aa55e3Rebecca Silberstein                                                           mWifiMetrics);
121e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        mLooper.dispatchAll();
12279d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        return newSoftApManager;
123e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    }
124e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
12579d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    /** Verifies startSoftAp will use default config if AP configuration is not provided. */
126e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    @Test
127e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    public void startSoftApWithoutConfig() throws Exception {
12879d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        startSoftApAndVerifyEnabled(null);
12979d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    }
130e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
13179d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    /** Verifies startSoftAp will use provided config and start AP. */
13279d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    @Test
13379d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    public void startSoftApWithConfig() throws Exception {
13479d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        WifiConfiguration config = new WifiConfiguration();
13579d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        config.apBand = WifiConfiguration.AP_BAND_2GHZ;
13679d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        config.SSID = TEST_SSID;
13779d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        startSoftApAndVerifyEnabled(config);
13879d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    }
139e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
1405c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein
1415c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein    /**
1425c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein     * Verifies startSoftAp will start with the hiddenSSID param set when it is set to true in the
1435c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein     * supplied config.
1445c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein     */
1455c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein    @Test
1465c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein    public void startSoftApWithHiddenSsidTrueInConfig() throws Exception {
1475c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein        WifiConfiguration config = new WifiConfiguration();
1485c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein        config.apBand = WifiConfiguration.AP_BAND_2GHZ;
1495c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein        config.SSID = TEST_SSID;
1505c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein        config.hiddenSSID = true;
1515c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein        startSoftApAndVerifyEnabled(config);
1525c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein    }
1535c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein
15479d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    /** Tests softap startup if default config fails to load. **/
15579d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    @Test
15679d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    public void startSoftApDefaultConfigFailedToLoad() throws Exception {
1574e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein        when(mApInterface.asBinder()).thenReturn(mApInterfaceBinder);
1584e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein        when(mApInterface.startHostapd()).thenReturn(true);
1594e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein        when(mApInterface.stopHostapd()).thenReturn(true);
16079d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        when(mWifiApConfigStore.getApConfiguration()).thenReturn(null);
1614e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein        SoftApManager newSoftApManager = new SoftApManager(mLooper.getLooper(),
1624e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein                                                           mWifiNative,
1634e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein                                                           TEST_COUNTRY_CODE,
1644e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein                                                           mListener,
1654e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein                                                           mApInterface,
1664e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein                                                           mNmService,
1674e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein                                                           mWifiApConfigStore,
1684e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein                                                           null,
1694e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein                                                           mWifiMetrics);
1704e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein        mLooper.dispatchAll();
1714e0a1bafa7a86e2840c855846f3fdaee9cd00424Rebecca Silberstein        newSoftApManager.start();
17279d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        mLooper.dispatchAll();
17379d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
17479d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein                WifiManager.SAP_START_FAILURE_GENERAL);
175e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    }
176e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
177be40e20f6995d9d11c8270502120a07785dde270Daniel Erat    /** Tests the handling of stop command when soft AP is not started. */
178e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    @Test
179e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    public void stopWhenNotStarted() throws Exception {
18079d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        mSoftApManager = createSoftApManager(null);
181e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        mSoftApManager.stop();
182e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        mLooper.dispatchAll();
183e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        /* Verify no state changes. */
184e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        verify(mListener, never()).onStateChanged(anyInt(), anyInt());
185e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    }
186e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
187be40e20f6995d9d11c8270502120a07785dde270Daniel Erat    /** Tests the handling of stop command when soft AP is started. */
188e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    @Test
189e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    public void stopWhenStarted() throws Exception {
19079d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        startSoftApAndVerifyEnabled(null);
191e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
192e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        InOrder order = inOrder(mListener);
193e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
194e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        mSoftApManager.stop();
195e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        mLooper.dispatchAll();
196e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu
197974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley        verify(mApInterface).stopHostapd();
198e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
199e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
200e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu    }
201be40e20f6995d9d11c8270502120a07785dde270Daniel Erat
202736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley    @Test
203736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley    public void handlesWificondInterfaceDeath() throws Exception {
20479d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        startSoftApAndVerifyEnabled(null);
205736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley
206736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley        mDeathListenerCaptor.getValue().binderDied();
207736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley        mLooper.dispatchAll();
208736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley        InOrder order = inOrder(mListener);
209736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
210736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
211736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley                WifiManager.SAP_START_FAILURE_GENERAL);
212736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley    }
213736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley
214be40e20f6995d9d11c8270502120a07785dde270Daniel Erat    /** Starts soft AP and verifies that it is enabled successfully. */
21579d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein    protected void startSoftApAndVerifyEnabled(WifiConfiguration config) throws Exception {
21679d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        String expectedSSID;
2175c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein        boolean expectedHiddenSsid;
218fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley        InOrder order = inOrder(mListener, mApInterfaceBinder, mApInterface, mNmService);
219be40e20f6995d9d11c8270502120a07785dde270Daniel Erat
220be40e20f6995d9d11c8270502120a07785dde270Daniel Erat        when(mWifiNative.isHalStarted()).thenReturn(false);
221be40e20f6995d9d11c8270502120a07785dde270Daniel Erat        when(mWifiNative.setCountryCodeHal(TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT)))
222be40e20f6995d9d11c8270502120a07785dde270Daniel Erat                .thenReturn(true);
22379d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein
22479d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        mSoftApManager = createSoftApManager(config);
22579d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        if (config == null) {
22679d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein            when(mWifiApConfigStore.getApConfiguration()).thenReturn(mDefaultApConfig);
22779d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein            expectedSSID = mDefaultApConfig.SSID;
2285c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein            expectedHiddenSsid = mDefaultApConfig.hiddenSSID;
22979d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        } else {
23079d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein            expectedSSID = config.SSID;
2315c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein            expectedHiddenSsid = config.hiddenSSID;
23279d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        }
2335c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein
23479d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein        mSoftApManager.start();
235be40e20f6995d9d11c8270502120a07785dde270Daniel Erat        mLooper.dispatchAll();
236be40e20f6995d9d11c8270502120a07785dde270Daniel Erat        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
237736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley        order.verify(mApInterfaceBinder).linkToDeath(mDeathListenerCaptor.capture(), eq(0));
238fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley        order.verify(mNmService).registerObserver(mNetworkObserverCaptor.capture());
239974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley        order.verify(mApInterface).writeHostapdConfig(
2405c5b37f9cc52daff34b8509dbda68e754fbbcacbRebecca Silberstein                eq(expectedSSID.getBytes(StandardCharsets.UTF_8)), eq(expectedHiddenSsid),
24179d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silberstein                anyInt(), anyInt(), any());
242974f4ecb02b4560f18bfdaed3f6a2c78e5d42ee0Christopher Wiley        order.verify(mApInterface).startHostapd();
243fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley        mNetworkObserverCaptor.getValue().interfaceLinkStateChanged(TEST_INTERFACE_NAME, true);
244fe3e7f39c4acf1517b31d6ff7123d075c1e6de25Christopher Wiley        mLooper.dispatchAll();
245be40e20f6995d9d11c8270502120a07785dde270Daniel Erat        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
246be40e20f6995d9d11c8270502120a07785dde270Daniel Erat    }
247be40e20f6995d9d11c8270502120a07785dde270Daniel Erat
248be40e20f6995d9d11c8270502120a07785dde270Daniel Erat    /** Verifies that soft AP was not disabled. */
249be40e20f6995d9d11c8270502120a07785dde270Daniel Erat    protected void verifySoftApNotDisabled() throws Exception {
250be40e20f6995d9d11c8270502120a07785dde270Daniel Erat        verify(mListener, never()).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
251be40e20f6995d9d11c8270502120a07785dde270Daniel Erat        verify(mListener, never()).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
252be40e20f6995d9d11c8270502120a07785dde270Daniel Erat    }
253e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu}
254