Skip to content

Commit 59c73b9

Browse files
isheriffAndroid (Google) Code Review
authored andcommitted
Merge "Convert soft ap config store to state machine" into ics-mr1
2 parents b78ae75 + 9575a1b commit 59c73b9

File tree

3 files changed

+201
-160
lines changed

3 files changed

+201
-160
lines changed

services/java/com/android/server/WifiService.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,7 @@ public int getWifiApEnabledState() {
619619
*/
620620
public WifiConfiguration getWifiApConfiguration() {
621621
enforceAccessPermission();
622-
if (mWifiStateMachineChannel != null) {
623-
return mWifiStateMachine.syncGetWifiApConfiguration(mWifiStateMachineChannel);
624-
} else {
625-
Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
626-
return null;
627-
}
622+
return mWifiStateMachine.syncGetWifiApConfiguration();
628623
}
629624

630625
/**

wifi/java/android/net/wifi/WifiApConfigStore.java

Lines changed: 138 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@
1919
import android.content.Context;
2020
import android.net.wifi.WifiConfiguration.KeyMgmt;
2121
import android.os.Environment;
22-
import android.os.Message;
2322
import android.os.Handler;
24-
import android.os.HandlerThread;
23+
import android.os.Message;
24+
import android.os.Messenger;
2525
import android.util.Log;
2626

27+
import com.android.internal.util.AsyncChannel;
28+
import com.android.internal.R;
29+
import com.android.internal.util.State;
30+
import com.android.internal.util.StateMachine;
31+
2732
import java.io.BufferedInputStream;
2833
import java.io.BufferedOutputStream;
2934
import java.io.DataInputStream;
@@ -34,148 +39,174 @@
3439
import java.net.InetAddress;
3540
import java.util.UUID;
3641

37-
import com.android.internal.R;
38-
39-
4042
/**
4143
* Provides API to the WifiStateMachine for doing read/write access
4244
* to soft access point configuration
4345
*/
44-
class WifiApConfigStore {
46+
class WifiApConfigStore extends StateMachine {
4547

46-
private static Context sContext;
48+
private Context mContext;
4749
private static final String TAG = "WifiApConfigStore";
4850

4951
private static final String AP_CONFIG_FILE = Environment.getDataDirectory() +
5052
"/misc/wifi/softap.conf";
5153

5254
private static final int AP_CONFIG_FILE_VERSION = 1;
5355

54-
private static WifiConfiguration sApConfig = new WifiConfiguration();
55-
private static final Object sApConfigLock = new Object();
56+
private State mDefaultState = new DefaultState();
57+
private State mInactiveState = new InactiveState();
58+
private State mActiveState = new ActiveState();
59+
60+
private WifiConfiguration mWifiApConfig = null;
61+
private AsyncChannel mReplyChannel = new AsyncChannel();
5662

57-
private static FileReadWriteHandler sFileReadWriteHandler;
58-
private static final int READ_AP_CONFIG = 1;
59-
private static final int WRITE_AP_CONFIG = 2;
63+
WifiApConfigStore(Context context, Handler target) {
64+
super(TAG, target.getLooper());
6065

61-
static void initialize(Context context) {
62-
sContext = context;
66+
mContext = context;
67+
addState(mDefaultState);
68+
addState(mInactiveState, mDefaultState);
69+
addState(mActiveState, mDefaultState);
6370

64-
/* File operations happen on a seperate thread */
65-
HandlerThread configThread = new HandlerThread("WifiApConfigStore");
66-
configThread.start();
67-
sFileReadWriteHandler = new FileReadWriteHandler(configThread.getLooper());
68-
Message.obtain(sFileReadWriteHandler, READ_AP_CONFIG).sendToTarget();
71+
setInitialState(mInactiveState);
6972
}
7073

74+
public static WifiApConfigStore makeWifiApConfigStore(Context context, Handler target) {
75+
WifiApConfigStore s = new WifiApConfigStore(context, target);
76+
s.start();
77+
return s;
78+
}
7179

72-
static void setApConfiguration(WifiConfiguration config) {
73-
synchronized (sApConfigLock) {
74-
sApConfig = config;
80+
class DefaultState extends State {
81+
public boolean processMessage(Message message) {
82+
switch (message.what) {
83+
case WifiStateMachine.CMD_SET_AP_CONFIG:
84+
case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED:
85+
Log.e(TAG, "Unexpected message: " + message);
86+
break;
87+
case WifiStateMachine.CMD_REQUEST_AP_CONFIG:
88+
mReplyChannel.replyToMessage(message,
89+
WifiStateMachine.CMD_RESPONSE_AP_CONFIG, mWifiApConfig);
90+
break;
91+
default:
92+
Log.e(TAG, "Failed to handle " + message);
93+
break;
94+
}
95+
return HANDLED;
7596
}
76-
Message.obtain(sFileReadWriteHandler, WRITE_AP_CONFIG, new WifiConfiguration(config))
77-
.sendToTarget();
7897
}
7998

80-
static WifiConfiguration getApConfiguration() {
81-
synchronized (sApConfigLock) {
82-
return new WifiConfiguration(sApConfig);
99+
class InactiveState extends State {
100+
public boolean processMessage(Message message) {
101+
switch (message.what) {
102+
case WifiStateMachine.CMD_SET_AP_CONFIG:
103+
mWifiApConfig = (WifiConfiguration) message.obj;
104+
transitionTo(mActiveState);
105+
break;
106+
default:
107+
return NOT_HANDLED;
108+
}
109+
return HANDLED;
83110
}
84111
}
85112

86-
/**
87-
* File read/write handler
88-
*/
89-
private static class FileReadWriteHandler extends Handler {
90-
91-
public FileReadWriteHandler(android.os.Looper looper) {
92-
super(looper);
113+
class ActiveState extends State {
114+
public void enter() {
115+
new Thread(new Runnable() {
116+
public void run() {
117+
writeApConfiguration(mWifiApConfig);
118+
sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED);
119+
}
120+
}).start();
93121
}
94122

95-
@Override
96-
public void handleMessage(Message msg) {
97-
switch (msg.what) {
98-
case WRITE_AP_CONFIG:
99-
writeApConfiguration((WifiConfiguration) msg.obj);
123+
public boolean processMessage(Message message) {
124+
switch (message.what) {
125+
//TODO: have feedback to the user when we do this
126+
//to indicate the write is currently in progress
127+
case WifiStateMachine.CMD_SET_AP_CONFIG:
128+
deferMessage(message);
100129
break;
101-
case READ_AP_CONFIG:
102-
readApConfiguration();
130+
case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED:
131+
transitionTo(mInactiveState);
103132
break;
104133
default:
105-
Log.e(TAG, "Unknown command in FileReadWriteHandler: " + msg);
106-
break;
134+
return NOT_HANDLED;
107135
}
136+
return HANDLED;
108137
}
138+
}
109139

110-
private static void writeApConfiguration(final WifiConfiguration config) {
111-
DataOutputStream out = null;
112-
try {
113-
out = new DataOutputStream(new BufferedOutputStream(
114-
new FileOutputStream(AP_CONFIG_FILE)));
115-
116-
out.writeInt(AP_CONFIG_FILE_VERSION);
117-
out.writeUTF(config.SSID);
118-
int authType = config.getAuthType();
119-
out.writeInt(authType);
120-
if(authType != KeyMgmt.NONE) {
121-
out.writeUTF(config.preSharedKey);
122-
}
123-
} catch (IOException e) {
124-
Log.e(TAG, "Error writing hotspot configuration" + e);
125-
} finally {
126-
if (out != null) {
127-
try {
128-
out.close();
129-
} catch (IOException e) {}
130-
}
131-
}
132-
}
140+
void loadApConfiguration() {
141+
DataInputStream in = null;
142+
try {
143+
WifiConfiguration config = new WifiConfiguration();
144+
in = new DataInputStream(new BufferedInputStream(new FileInputStream(
145+
AP_CONFIG_FILE)));
133146

134-
private static void readApConfiguration() {
135-
DataInputStream in = null;
136-
try {
137-
WifiConfiguration config = new WifiConfiguration();
138-
in = new DataInputStream(new BufferedInputStream(new FileInputStream(
139-
AP_CONFIG_FILE)));
140-
141-
int version = in.readInt();
142-
if (version != 1) {
143-
Log.e(TAG, "Bad version on hotspot configuration file, set defaults");
144-
setDefaultApConfiguration();
145-
return;
146-
}
147-
config.SSID = in.readUTF();
148-
int authType = in.readInt();
149-
config.allowedKeyManagement.set(authType);
150-
if (authType != KeyMgmt.NONE) {
151-
config.preSharedKey = in.readUTF();
152-
}
153-
synchronized (sApConfigLock) {
154-
sApConfig = config;
155-
}
156-
} catch (IOException ignore) {
147+
int version = in.readInt();
148+
if (version != 1) {
149+
Log.e(TAG, "Bad version on hotspot configuration file, set defaults");
157150
setDefaultApConfiguration();
158-
} finally {
159-
if (in != null) {
160-
try {
161-
in.close();
162-
} catch (IOException e) {}
163-
}
151+
return;
152+
}
153+
config.SSID = in.readUTF();
154+
int authType = in.readInt();
155+
config.allowedKeyManagement.set(authType);
156+
if (authType != KeyMgmt.NONE) {
157+
config.preSharedKey = in.readUTF();
158+
}
159+
mWifiApConfig = config;
160+
} catch (IOException ignore) {
161+
setDefaultApConfiguration();
162+
} finally {
163+
if (in != null) {
164+
try {
165+
in.close();
166+
} catch (IOException e) {}
164167
}
165168
}
169+
}
166170

167-
/* Generate a default WPA2 based configuration with a random password.
168-
We are changing the Wifi Ap configuration storage from secure settings to a
169-
flat file accessible only by the system. A WPA2 based default configuration
170-
will keep the device secure after the update */
171-
private static void setDefaultApConfiguration() {
172-
WifiConfiguration config = new WifiConfiguration();
173-
config.SSID = sContext.getString(R.string.wifi_tether_configure_ssid_default);
174-
config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
175-
String randomUUID = UUID.randomUUID().toString();
176-
//first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
177-
config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9,13);
178-
setApConfiguration(config);
171+
Messenger getMessenger() {
172+
return new Messenger(getHandler());
173+
}
174+
175+
private void writeApConfiguration(final WifiConfiguration config) {
176+
DataOutputStream out = null;
177+
try {
178+
out = new DataOutputStream(new BufferedOutputStream(
179+
new FileOutputStream(AP_CONFIG_FILE)));
180+
181+
out.writeInt(AP_CONFIG_FILE_VERSION);
182+
out.writeUTF(config.SSID);
183+
int authType = config.getAuthType();
184+
out.writeInt(authType);
185+
if(authType != KeyMgmt.NONE) {
186+
out.writeUTF(config.preSharedKey);
187+
}
188+
} catch (IOException e) {
189+
Log.e(TAG, "Error writing hotspot configuration" + e);
190+
} finally {
191+
if (out != null) {
192+
try {
193+
out.close();
194+
} catch (IOException e) {}
195+
}
179196
}
180197
}
198+
199+
/* Generate a default WPA2 based configuration with a random password.
200+
We are changing the Wifi Ap configuration storage from secure settings to a
201+
flat file accessible only by the system. A WPA2 based default configuration
202+
will keep the device secure after the update */
203+
private void setDefaultApConfiguration() {
204+
WifiConfiguration config = new WifiConfiguration();
205+
config.SSID = mContext.getString(R.string.wifi_tether_configure_ssid_default);
206+
config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
207+
String randomUUID = UUID.randomUUID().toString();
208+
//first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
209+
config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9,13);
210+
sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG, config);
211+
}
181212
}

0 commit comments

Comments
 (0)