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
17package com.android.server.wifi;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertTrue;
21import static org.mockito.Mockito.verify;
22import static org.mockito.Mockito.when;
23
24import android.content.Context;
25import android.net.wifi.WifiConfiguration;
26import android.net.wifi.WifiConfiguration.KeyMgmt;
27import android.test.suitebuilder.annotation.SmallTest;
28
29import com.android.internal.R;
30
31import org.junit.After;
32import org.junit.Before;
33import org.junit.Test;
34import org.mockito.Mock;
35import org.mockito.MockitoAnnotations;
36
37import java.io.File;
38import java.lang.reflect.Method;
39
40/**
41 * Unit tests for {@link com.android.server.wifi.WifiApConfigStore}.
42 */
43@SmallTest
44public class WifiApConfigStoreTest {
45
46    private static final String TAG = "WifiApConfigStoreTest";
47
48    private static final String TEST_AP_CONFIG_FILE_PREFIX = "APConfig_";
49    private static final String TEST_DEFAULT_2G_CHANNEL_LIST = "1,2,3,4,5,6";
50    private static final String TEST_DEFAULT_AP_SSID = "TestAP";
51    private static final String TEST_CONFIGURED_AP_SSID = "ConfiguredAP";
52
53    @Mock Context mContext;
54    @Mock BackupManagerProxy mBackupManagerProxy;
55    File mApConfigFile;
56
57    @Before
58    public void setUp() throws Exception {
59        MockitoAnnotations.initMocks(this);
60
61        /* Create a temporary file for AP config file storage. */
62        mApConfigFile = File.createTempFile(TEST_AP_CONFIG_FILE_PREFIX, "");
63
64        /* Setup expectations for Resources to return some default settings. */
65        MockResources resources = new MockResources();
66        resources.setString(R.string.config_wifi_framework_sap_2G_channel_list,
67                            TEST_DEFAULT_2G_CHANNEL_LIST);
68        resources.setString(R.string.wifi_tether_configure_ssid_default,
69                            TEST_DEFAULT_AP_SSID);
70        when(mContext.getResources()).thenReturn(resources);
71    }
72
73    @After
74    public void cleanUp() {
75        /* Remove the temporary AP config file. */
76        mApConfigFile.delete();
77    }
78
79    /**
80     * Generate a WifiConfiguration based on the specified parameters.
81     */
82    private WifiConfiguration setupApConfig(
83            String ssid, String preSharedKey, int keyManagement, int band, int channel) {
84        WifiConfiguration config = new WifiConfiguration();
85        config.SSID = ssid;
86        config.preSharedKey = preSharedKey;
87        config.allowedKeyManagement.set(keyManagement);
88        config.apBand = band;
89        config.apChannel = channel;
90        return config;
91    }
92
93    private void writeApConfigFile(WifiConfiguration config) throws Exception {
94        Method m = WifiApConfigStore.class.getDeclaredMethod(
95                "writeApConfiguration", String.class, WifiConfiguration.class);
96        m.setAccessible(true);
97        m.invoke(null, mApConfigFile.getPath(), config);
98    }
99
100    private void verifyApConfig(WifiConfiguration config1, WifiConfiguration config2) {
101        assertEquals(config1.SSID, config2.SSID);
102        assertEquals(config1.preSharedKey, config2.preSharedKey);
103        assertEquals(config1.getAuthType(), config2.getAuthType());
104        assertEquals(config1.apBand, config2.apBand);
105        assertEquals(config1.apChannel, config2.apChannel);
106    }
107
108    private void verifyDefaultApConfig(WifiConfiguration config) {
109        assertEquals(TEST_DEFAULT_AP_SSID, config.SSID);
110        assertTrue(config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK));
111    }
112
113    /**
114     * AP Configuration is not specified in the config file,
115     * WifiApConfigStore should fallback to use the default configuration.
116     */
117    @Test
118    public void initWithDefaultConfiguration() throws Exception {
119        WifiApConfigStore store = new WifiApConfigStore(
120                mContext, mBackupManagerProxy, mApConfigFile.getPath());
121        verifyDefaultApConfig(store.getApConfiguration());
122    }
123
124    /**
125     * Verify WifiApConfigStore can correctly load the existing configuration
126     * from the config file.
127     */
128    @Test
129    public void initWithExistingConfiguration() throws Exception {
130        WifiConfiguration expectedConfig = setupApConfig(
131                "ConfiguredAP",    /* SSID */
132                "randomKey",       /* preshared key */
133                KeyMgmt.WPA_EAP,   /* key management */
134                1,                 /* AP band (5GHz) */
135                40                 /* AP channel */);
136        writeApConfigFile(expectedConfig);
137        WifiApConfigStore store = new WifiApConfigStore(
138                mContext, mBackupManagerProxy, mApConfigFile.getPath());
139        verifyApConfig(expectedConfig, store.getApConfiguration());
140    }
141
142    /**
143     * Verify the handling of setting a null ap configuration.
144     * WifiApConfigStore should fallback to the default configuration when
145     * null ap configuration is provided.
146     */
147    @Test
148    public void setNullApConfiguration() throws Exception {
149        /* Initialize WifiApConfigStore with existing configuration. */
150        WifiConfiguration expectedConfig = setupApConfig(
151                "ConfiguredAP",    /* SSID */
152                "randomKey",       /* preshared key */
153                KeyMgmt.WPA_EAP,   /* key management */
154                1,                 /* AP band (5GHz) */
155                40                 /* AP channel */);
156        writeApConfigFile(expectedConfig);
157        WifiApConfigStore store = new WifiApConfigStore(
158                mContext, mBackupManagerProxy, mApConfigFile.getPath());
159        verifyApConfig(expectedConfig, store.getApConfiguration());
160
161        store.setApConfiguration(null);
162        verifyDefaultApConfig(store.getApConfiguration());
163        verify(mBackupManagerProxy).notifyDataChanged();
164    }
165
166    /**
167     * Verify AP configuration is correctly updated via setApConfiguration call.
168     */
169    @Test
170    public void updateApConfiguration() throws Exception {
171        /* Initialize WifiApConfigStore with default configuration. */
172        WifiApConfigStore store = new WifiApConfigStore(
173                mContext, mBackupManagerProxy, mApConfigFile.getPath());
174        verifyDefaultApConfig(store.getApConfiguration());
175
176        /* Update with a valid configuration. */
177        WifiConfiguration expectedConfig = setupApConfig(
178                "ConfiguredAP",    /* SSID */
179                "randomKey",       /* preshared key */
180                KeyMgmt.WPA_EAP,   /* key management */
181                1,                 /* AP band (5GHz) */
182                40                 /* AP channel */);
183        store.setApConfiguration(expectedConfig);
184        verifyApConfig(expectedConfig, store.getApConfiguration());
185        verify(mBackupManagerProxy).notifyDataChanged();
186    }
187}
188