summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Qiu <zqiu@google.com>2016-02-02 21:53:24 +0000
committerAndroid Partner Code Review <android-gerrit-partner@google.com>2016-02-02 21:53:24 +0000
commita51955bb18c047b2d7e4160f75b7e2dc876eb227 (patch)
tree0b18dd040b45df8e78e6f842655e08fdb88131f5
parent2e484f49a044c3d25da845e544c81b2bacfce714 (diff)
parentc79666b79e273ceaa2f74090b02ca6cf83c61387 (diff)
Merge "WifiApConfigStore refactoring" into mm-wireless-dev
-rw-r--r--service/java/com/android/server/wifi/FrameworkFacade.java4
-rw-r--r--service/java/com/android/server/wifi/WifiApConfigStore.java198
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java66
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java179
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java2
5 files changed, 283 insertions, 166 deletions
diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java
index 5ae01ae1e..20ad86073 100644
--- a/service/java/com/android/server/wifi/FrameworkFacade.java
+++ b/service/java/com/android/server/wifi/FrameworkFacade.java
@@ -65,8 +65,8 @@ public class FrameworkFacade {
return new SupplicantStateTracker(context, wifiStateMachine, configStore, handler);
}
- public WifiApConfigStore makeApConfigStore(Context context, Handler handler) {
- return WifiApConfigStore.makeWifiApConfigStore(context, handler);
+ public WifiApConfigStore makeApConfigStore(Context context) {
+ return new WifiApConfigStore(context);
}
public long getTxPackets(String iface) {
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index 68ac4b3b6..70cf30efe 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -20,15 +20,9 @@ import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
import android.util.Log;
import com.android.internal.R;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -41,132 +35,97 @@ import java.util.ArrayList;
import java.util.UUID;
/**
- * Provides API to the WifiStateMachine for doing read/write access
- * to soft access point configuration
+ * Provides API for reading/writing soft access point configuration.
*/
-public class WifiApConfigStore extends StateMachine {
+public class WifiApConfigStore {
- private Context mContext;
private static final String TAG = "WifiApConfigStore";
- private static final String AP_CONFIG_FILE = Environment.getDataDirectory() +
- "/misc/wifi/softap.conf";
+ private static final String DEFAULT_AP_CONFIG_FILE =
+ Environment.getDataDirectory() + "/misc/wifi/softap.conf";
private static final int AP_CONFIG_FILE_VERSION = 2;
- private State mDefaultState = new DefaultState();
- private State mInactiveState = new InactiveState();
- private State mActiveState = new ActiveState();
-
private WifiConfiguration mWifiApConfig = null;
- private AsyncChannel mReplyChannel = new AsyncChannel();
- public ArrayList <Integer> allowed2GChannel = null;
- WifiApConfigStore(Context context, Handler target) {
- super(TAG, target.getLooper());
+ private ArrayList<Integer> mAllowed2GChannel = null;
+
+ private final Context mContext;
+ private final String mApConfigFile;
+
+ WifiApConfigStore(Context context) {
+ this(context, DEFAULT_AP_CONFIG_FILE);
+ }
+ WifiApConfigStore(Context context, String apConfigFile) {
mContext = context;
- addState(mDefaultState);
- addState(mInactiveState, mDefaultState);
- addState(mActiveState, mDefaultState);
+ mApConfigFile = apConfigFile;
- setInitialState(mInactiveState);
String ap2GChannelListStr = mContext.getResources().getString(
R.string.config_wifi_framework_sap_2G_channel_list);
Log.d(TAG, "2G band allowed channels are:" + ap2GChannelListStr);
if (ap2GChannelListStr != null) {
- allowed2GChannel = new ArrayList<Integer>();
+ mAllowed2GChannel = new ArrayList<Integer>();
String channelList[] = ap2GChannelListStr.split(",");
for (String tmp : channelList) {
- allowed2GChannel.add(Integer.parseInt(tmp));
+ mAllowed2GChannel.add(Integer.parseInt(tmp));
}
}
- }
- public static WifiApConfigStore makeWifiApConfigStore(Context context, Handler target) {
- WifiApConfigStore s = new WifiApConfigStore(context, target);
- s.start();
- return s;
- }
+ /* Load AP configuration from persistent storage. */
+ mWifiApConfig = loadApConfiguration(mApConfigFile);
+ if (mWifiApConfig == null) {
+ /* Use default configuration. */
+ Log.d(TAG, "Fallback to use default AP configuration");
+ mWifiApConfig = getDefaultApConfiguration();
- class DefaultState extends State {
- public boolean processMessage(Message message) {
- switch (message.what) {
- case WifiStateMachine.CMD_SET_AP_CONFIG:
- case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED:
- Log.e(TAG, "Unexpected message: " + message);
- break;
- case WifiStateMachine.CMD_REQUEST_AP_CONFIG:
- mReplyChannel.replyToMessage(message,
- WifiStateMachine.CMD_RESPONSE_AP_CONFIG, mWifiApConfig);
- break;
- default:
- Log.e(TAG, "Failed to handle " + message);
- break;
- }
- return HANDLED;
+ /* Save the default configuration to persistent storage. */
+ writeApConfiguration(mApConfigFile, mWifiApConfig);
}
}
- class InactiveState extends State {
- public boolean processMessage(Message message) {
- switch (message.what) {
- case WifiStateMachine.CMD_SET_AP_CONFIG:
- WifiConfiguration config = (WifiConfiguration)message.obj;
- if (config.SSID != null) {
- mWifiApConfig = config;
- transitionTo(mActiveState);
- } else {
- Log.e(TAG, "Try to setup AP config without SSID: " + message);
- }
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
+ /**
+ * Return the current soft access point configuration.
+ */
+ public synchronized WifiConfiguration getApConfiguration() {
+ return mWifiApConfig;
}
- class ActiveState extends State {
- public void enter() {
- new Thread(new Runnable() {
- public void run() {
- writeApConfiguration(mWifiApConfig);
- sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED);
- }
- }).start();
+ /**
+ * Update the current soft access point configuration.
+ * Restore to default AP configuration if null is provided.
+ * This can be invoked under context of binder threads (WifiManager.setWifiApConfiguration)
+ * and WifiStateMachine thread (CMD_START_AP).
+ */
+ public synchronized void setApConfiguration(WifiConfiguration config) {
+ if (config == null) {
+ mWifiApConfig = getDefaultApConfiguration();
+ } else {
+ mWifiApConfig = config;
}
+ writeApConfiguration(mApConfigFile, mWifiApConfig);
+ }
- public boolean processMessage(Message message) {
- switch (message.what) {
- //TODO: have feedback to the user when we do this
- //to indicate the write is currently in progress
- case WifiStateMachine.CMD_SET_AP_CONFIG:
- deferMessage(message);
- break;
- case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED:
- transitionTo(mInactiveState);
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
+ public ArrayList<Integer> getAllowed2GChannel() {
+ return mAllowed2GChannel;
}
- void loadApConfiguration() {
+ /**
+ * Load AP configuration from persistent storage.
+ */
+ private static WifiConfiguration loadApConfiguration(final String filename) {
+ WifiConfiguration config = null;
DataInputStream in = null;
try {
- WifiConfiguration config = new WifiConfiguration();
- in = new DataInputStream(new BufferedInputStream(new FileInputStream(
- AP_CONFIG_FILE)));
+ config = new WifiConfiguration();
+ in = new DataInputStream(
+ new BufferedInputStream(new FileInputStream(filename)));
int version = in.readInt();
if ((version != 1) && (version != 2)) {
- Log.e(TAG, "Bad version on hotspot configuration file, set defaults");
- setDefaultApConfiguration();
- return;
+ Log.e(TAG, "Bad version on hotspot configuration file");
+ return null;
}
config.SSID = in.readUTF();
@@ -180,28 +139,30 @@ public class WifiApConfigStore extends StateMachine {
if (authType != KeyMgmt.NONE) {
config.preSharedKey = in.readUTF();
}
-
- mWifiApConfig = config;
- } catch (IOException ignore) {
- setDefaultApConfiguration();
+ } catch (IOException e) {
+ Log.e(TAG, "Error reading hotspot configuration " + e);
+ config = null;
} finally {
if (in != null) {
try {
in.close();
- } catch (IOException e) {}
+ } catch (IOException e) {
+ Log.e(TAG, "Error closing hotspot configuration during read" + e);
+ }
}
}
+ return config;
}
- Messenger getMessenger() {
- return new Messenger(getHandler());
- }
-
- private void writeApConfiguration(final WifiConfiguration config) {
+ /**
+ * Write AP configuration to persistent storage.
+ */
+ private static boolean writeApConfiguration(final String filename,
+ final WifiConfiguration config) {
DataOutputStream out = null;
try {
out = new DataOutputStream(new BufferedOutputStream(
- new FileOutputStream(AP_CONFIG_FILE)));
+ new FileOutputStream(filename)));
out.writeInt(AP_CONFIG_FILE_VERSION);
out.writeUTF(config.SSID);
@@ -209,32 +170,39 @@ public class WifiApConfigStore extends StateMachine {
out.writeInt(config.apChannel);
int authType = config.getAuthType();
out.writeInt(authType);
- if(authType != KeyMgmt.NONE) {
+ if (authType != KeyMgmt.NONE) {
out.writeUTF(config.preSharedKey);
}
} catch (IOException e) {
Log.e(TAG, "Error writing hotspot configuration" + e);
+ return false;
} finally {
if (out != null) {
try {
out.close();
- } catch (IOException e) {}
+ } catch (IOException e) {
+ Log.e(TAG, "Error closing hotspot configuration during write" + e);
+ return false;
+ }
}
}
+ return true;
}
- /* Generate a default WPA2 based configuration with a random password.
- We are changing the Wifi Ap configuration storage from secure settings to a
- flat file accessible only by the system. A WPA2 based default configuration
- will keep the device secure after the update */
- private void setDefaultApConfiguration() {
+ /**
+ * Generate a default WPA2 based configuration with a random password.
+ * We are changing the Wifi Ap configuration storage from secure settings to a
+ * flat file accessible only by the system. A WPA2 based default configuration
+ * will keep the device secure after the update.
+ */
+ private WifiConfiguration getDefaultApConfiguration() {
WifiConfiguration config = new WifiConfiguration();
config.SSID = mContext.getResources().getString(
R.string.wifi_tether_configure_ssid_default);
config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
String randomUUID = UUID.randomUUID().toString();
//first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
- config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9,13);
- sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG, config);
+ config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
+ return config;
}
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index eedde4bde..d3af95da0 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -611,7 +611,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
// Used to initiate a connection with WifiP2pService
private AsyncChannel mWifiP2pChannel;
- private AsyncChannel mWifiApConfigChannel;
private WifiScanner mWifiScanner;
@@ -659,14 +658,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
static final int CMD_START_AP_FAILURE = BASE + 23;
/* Stop the soft access point */
static final int CMD_STOP_AP = BASE + 24;
- /* Set the soft access point configuration */
- static final int CMD_SET_AP_CONFIG = BASE + 25;
- /* Soft access point configuration set completed */
- static final int CMD_SET_AP_CONFIG_COMPLETED = BASE + 26;
- /* Request the soft access point configuration */
- static final int CMD_REQUEST_AP_CONFIG = BASE + 27;
- /* Response to access point configuration request */
- static final int CMD_RESPONSE_AP_CONFIG = BASE + 28;
/* Invoked when getting a tether state change notification */
static final int CMD_TETHER_STATE_CHANGE = BASE + 29;
/* A delayed message sent to indicate tether state change failed to arrive */
@@ -2136,14 +2127,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
}
public void setWifiApConfiguration(WifiConfiguration config) {
- mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
+ mWifiApConfigStore.setApConfiguration(config);
}
public WifiConfiguration syncGetWifiApConfiguration() {
- Message resultMsg = mWifiApConfigChannel.sendMessageSynchronously(CMD_REQUEST_AP_CONFIG);
- WifiConfiguration ret = (WifiConfiguration) resultMsg.obj;
- resultMsg.recycle();
- return ret;
+ return mWifiApConfigStore.getApConfiguration();
}
/**
@@ -5071,16 +5059,17 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
int[] channel;
if (apBand == 0) {
- if (mWifiApConfigStore.allowed2GChannel == null ||
- mWifiApConfigStore.allowed2GChannel.size() == 0) {
+ ArrayList<Integer> allowed2GChannel =
+ mWifiApConfigStore.getAllowed2GChannel();
+ if (allowed2GChannel == null || allowed2GChannel.size() == 0) {
//most safe channel to use
if(DBG) {
Log.d(TAG, "No specified 2G allowed channel list");
}
apChannel = 6;
} else {
- int index = mRandom.nextInt(mWifiApConfigStore.allowed2GChannel.size());
- apChannel = mWifiApConfigStore.allowed2GChannel.get(index).intValue();
+ int index = mRandom.nextInt(allowed2GChannel.size());
+ apChannel = allowed2GChannel.get(index).intValue();
}
} else {
//5G without DFS
@@ -5451,11 +5440,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
case CMD_ENABLE_ALL_NETWORKS:
case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
case DhcpStateMachine.CMD_POST_DHCP_ACTION:
- /* Handled by WifiApConfigStore */
- case CMD_SET_AP_CONFIG:
- case CMD_SET_AP_CONFIG_COMPLETED:
- case CMD_REQUEST_AP_CONFIG:
- case CMD_RESPONSE_AP_CONFIG:
case CMD_NO_NETWORKS_PERIODIC_SCAN:
case CMD_DISABLE_P2P_RSP:
case WifiMonitor.SUP_REQUEST_IDENTITY:
@@ -5621,12 +5605,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
mWifiP2pServiceImpl.getP2pStateMachineMessenger());
}
- if (mWifiApConfigChannel == null) {
- mWifiApConfigChannel = new AsyncChannel();
- mWifiApConfigStore = mFacade.makeApConfigStore(mContext, getHandler());
- mWifiApConfigStore.loadApConfiguration();
- mWifiApConfigChannel.connectSync(mContext, getHandler(),
- mWifiApConfigStore.getMessenger());
+ if (mWifiApConfigStore == null) {
+ mWifiApConfigStore = mFacade.makeApConfigStore(mContext);
}
if (mWifiConfigStore.enableHalBasedPno.get()) {
@@ -6541,12 +6521,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
case CMD_START_SUPPLICANT:
s = "CMD_START_SUPPLICANT";
break;
- case CMD_REQUEST_AP_CONFIG:
- s = "CMD_REQUEST_AP_CONFIG";
- break;
- case CMD_RESPONSE_AP_CONFIG:
- s = "CMD_RESPONSE_AP_CONFIG";
- break;
case CMD_TETHER_STATE_CHANGE:
s = "CMD_TETHER_STATE_CHANGE";
break;
@@ -9562,14 +9536,19 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
public void enter() {
final Message message = getCurrentMessage();
if (message.what == CMD_START_AP) {
- final WifiConfiguration config = (WifiConfiguration) message.obj;
+ WifiConfiguration config = (WifiConfiguration) message.obj;
if (config == null) {
- mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG);
+ /**
+ * Configuration not provided in the command, fallback to use the current
+ * configuration.
+ */
+ config = mWifiApConfigStore.getApConfiguration();
} else {
- mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
- startSoftApWithConfig(config);
+ /* Update AP configuration. */
+ mWifiApConfigStore.setApConfiguration(config);
}
+ startSoftApWithConfig(config);
} else {
throw new RuntimeException("Illegal transition to SoftApStartingState: " + message);
}
@@ -9593,15 +9572,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
case CMD_TETHER_STATE_CHANGE:
deferMessage(message);
break;
- case WifiStateMachine.CMD_RESPONSE_AP_CONFIG:
- WifiConfiguration config = (WifiConfiguration) message.obj;
- if (config != null) {
- startSoftApWithConfig(config);
- } else {
- loge("Softap config is null!");
- sendMessage(CMD_START_AP_FAILURE, WifiManager.SAP_START_FAILURE_GENERAL);
- }
- break;
case CMD_START_AP_SUCCESS:
setWifiApState(WIFI_AP_STATE_ENABLED, 0);
transitionTo(mSoftApStartedState);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
new file mode 100644
index 000000000..aedb5430f
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.internal.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.lang.reflect.Method;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.WifiApConfigStore}.
+ */
+@SmallTest
+public class WifiApConfigStoreTest {
+
+ private static final String TAG = "WifiApConfigStoreTest";
+
+ private static final String TEST_AP_CONFIG_FILE_PREFIX = "APConfig_";
+ private static final String TEST_DEFAULT_2G_CHANNEL_LIST = "1,2,3,4,5,6";
+ private static final String TEST_DEFAULT_AP_SSID = "TestAP";
+ private static final String TEST_CONFIGURED_AP_SSID = "ConfiguredAP";
+
+ @Mock Context mContext;
+ File mApConfigFile;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ /* Create a temporary file for AP config file storage. */
+ mApConfigFile = File.createTempFile(TEST_AP_CONFIG_FILE_PREFIX, "");
+
+ /* Setup expectations for Resources to return some default settings. */
+ MockResources resources = new MockResources();
+ resources.setString(R.string.config_wifi_framework_sap_2G_channel_list,
+ TEST_DEFAULT_2G_CHANNEL_LIST);
+ resources.setString(R.string.wifi_tether_configure_ssid_default,
+ TEST_DEFAULT_AP_SSID);
+ when(mContext.getResources()).thenReturn(resources);
+ }
+
+ @After
+ public void cleanUp() {
+ /* Remove the temporary AP config file. */
+ mApConfigFile.delete();
+ }
+
+ /**
+ * Generate a WifiConfiguration based on the specified parameters.
+ */
+ private WifiConfiguration setupApConfig(
+ String ssid, String preSharedKey, int keyManagement, int band, int channel) {
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = ssid;
+ config.preSharedKey = preSharedKey;
+ config.allowedKeyManagement.set(keyManagement);
+ config.apBand = band;
+ config.apChannel = channel;
+ return config;
+ }
+
+ private boolean writeApConfigFile(WifiConfiguration config) throws Exception {
+ Method m = WifiApConfigStore.class.getDeclaredMethod(
+ "writeApConfiguration", String.class, WifiConfiguration.class);
+ m.setAccessible(true);
+ return (boolean) m.invoke(null, mApConfigFile.getPath(), config);
+ }
+
+ private void verifyApConfig(WifiConfiguration config1, WifiConfiguration config2) {
+ assertEquals(config1.SSID, config2.SSID);
+ assertEquals(config1.preSharedKey, config2.preSharedKey);
+ assertEquals(config1.getAuthType(), config2.getAuthType());
+ assertEquals(config1.apBand, config2.apBand);
+ assertEquals(config1.apChannel, config2.apChannel);
+ }
+
+ private void verifyDefaultApConfig(WifiConfiguration config) {
+ assertEquals(TEST_DEFAULT_AP_SSID, config.SSID);
+ assertTrue(config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK));
+ }
+
+ /**
+ * AP Configuration is not specified in the config file,
+ * WifiApConfigStore should fallback to use the default configuration.
+ */
+ @Test
+ public void initWithDefaultConfiguration() throws Exception {
+ WifiApConfigStore store = new WifiApConfigStore(mContext, mApConfigFile.getPath());
+ verifyDefaultApConfig(store.getApConfiguration());
+ }
+
+ /**
+ * Verify WifiApConfigStore can correctly load the existing configuration
+ * from the config file.
+ */
+ @Test
+ public void initWithExistingConfiguration() throws Exception {
+ WifiConfiguration expectedConfig = setupApConfig(
+ "ConfiguredAP", /* SSID */
+ "randomKey", /* preshared key */
+ KeyMgmt.WPA_EAP, /* key management */
+ 1, /* AP band (5GHz) */
+ 40 /* AP channel */);
+ assertTrue(writeApConfigFile(expectedConfig));
+ WifiApConfigStore store = new WifiApConfigStore(mContext, mApConfigFile.getPath());
+ verifyApConfig(expectedConfig, store.getApConfiguration());
+ }
+
+ /**
+ * Verify the handling of setting a null ap configuration.
+ * WifiApConfigStore should fallback to the default configuration when
+ * null ap configuration is provided.
+ */
+ @Test
+ public void setNullApConfiguration() throws Exception {
+ /* Initialize WifiApConfigStore with existing configuration. */
+ WifiConfiguration expectedConfig = setupApConfig(
+ "ConfiguredAP", /* SSID */
+ "randomKey", /* preshared key */
+ KeyMgmt.WPA_EAP, /* key management */
+ 1, /* AP band (5GHz) */
+ 40 /* AP channel */);
+ assertTrue(writeApConfigFile(expectedConfig));
+ WifiApConfigStore store = new WifiApConfigStore(mContext, mApConfigFile.getPath());
+ verifyApConfig(expectedConfig, store.getApConfiguration());
+
+ store.setApConfiguration(null);
+ verifyDefaultApConfig(store.getApConfiguration());
+ }
+
+ /**
+ * Verify AP configuration is correctly updated via setApConfiguration call.
+ */
+ @Test
+ public void updateApConfiguration() throws Exception {
+ /* Initialize WifiApConfigStore with default configuration. */
+ WifiApConfigStore store = new WifiApConfigStore(mContext, mApConfigFile.getPath());
+ verifyDefaultApConfig(store.getApConfiguration());
+
+ /* Update with a valid configuration. */
+ WifiConfiguration expectedConfig = setupApConfig(
+ "ConfiguredAP", /* SSID */
+ "randomKey", /* preshared key */
+ KeyMgmt.WPA_EAP, /* key management */
+ 1, /* AP band (5GHz) */
+ 40 /* AP channel */);
+ store.setApConfiguration(expectedConfig);
+ verifyApConfig(expectedConfig, store.getApConfiguration());
+ }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index 41951f99a..0f1823fba 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -347,7 +347,7 @@ public class WifiStateMachineTest {
WifiManager.WIFI_FREQUENCY_BAND_AUTO)).thenReturn(
WifiManager.WIFI_FREQUENCY_BAND_AUTO);
- when(factory.makeApConfigStore(Mockito.eq(context), any(Handler.class)))
+ when(factory.makeApConfigStore(Mockito.eq(context)))
.thenCallRealMethod();
when(factory.makeSupplicantStateTracker(