http://blog.csdn.net/airk000/article/details/9273599
设置中开关:
packages/apps/Settings/src/com/android/settings/TetherSettings.java
|----private void startTethering()
| |----mWifiApEnabler.setSoftapEnabled(true);
packages/apps/Settings/src/com/android/settings/wifi/WifiApEnabler.java
|----public void setSoftapEnabled(boolean enable)
| |----mWifiManager.setWifiApEnabled(null, enable)
框架:
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
|----public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled)
| |----mService.setWifiApEnabled(wifiConfig, enabled);
IWifiManager.aidl
|----void setWifiApEnabled(in WifiConfiguration wifiConfig, boolean enable);
frameworks/base/services/java/com/android/server/WifiService.java
|----public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled)
| |----mWifiStateMachine.setWifiApEnabled(wifiConfig, enabled);
frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java
|----public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable)
| |----sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
| |----sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
1.JAVA API部分
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
2.服务器端进程
frameworks/base/services/java/com/android/server/WifiService.java
消息循环,状态机
frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java
public WifiStateMachine(Context context, String wlanInterface) {
mWifiConfigStore = new WifiConfigStore(context, mWifiNative);
WifiApConfigStore wifiApConfigStore = WifiApConfigStore.makeWifiApConfigStore(
context, getHandler());
wifiApConfigStore.loadApConfiguration(); // private static final String AP_CONFIG_FILE = Environment.getDataDirectory() + "/misc/wifi/softap.conf";
mWifiApConfigChannel.connectSync(mContext, getHandler(), wifiApConfigStore.getMessenger());
}
class Initial State extends State {
if(mWifiNative.isDriverLoaded()){
transitionTo(mDriverLoadedState);
}
else{ //因为最开始驱动都是没有加载的,所以进入transitionTo(mDriverUnloadedState);
transitionTo(mDriverUnloadedState);
}
WifiStateMachine进入DriverUnloadedState
classDriverUnloadedState extends State {
publicboolean processMessage(Message message) {
switch(message.what) {
case CMD_LOAD_DRIVER:
transitionTo(mDriverLoadingState);
这里会处理刚才的CMD_LOAD_DRIVER这个消息,继续切换到mDriverLoadingState
classDriverLoadingState extends State {
publicvoid enter() {
newThread(new Runnable() {
publicvoid run() {
mWakeLock.acquire();
//enablingstate
switch(message.arg1){
case WIFI_AP_STATE_ENABLING:}
if(mWifiNative.loadDriver()){ ---------------------------------------------------------->
sendMessage(CMD_LOAD_DRIVER_SUCCESS);
}
publicboolean processMessage(Message message) {
switch(message.what) {
caseCMD_LOAD_DRIVER_SUCCESS:
transitionTo(mDriverLoadedState);
}
这里会调用WifiNative.loadDriver()加载驱动,成功后发送消息CMD_LOAD_DRIVER_SUCCESS,然后进入mDriverLoadedState。否则发送CMD_LOAD_DRIVER_FAILURE,进入mDriverFailedState
来看另一个消息sendMessage(CMD_START_AP)
case CMD_START_AP:
class SoftApStartingState extends State {
public void enter() {
final Message message = getCurrentMessage();
if (message.what == CMD_START_AP) {
final WifiConfiguration config = (WifiConfiguration) message.obj;
if (config == null) {
mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG);
} else {
mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
startSoftApWithConfig(config);
}
frameworks/base/wifi/java/android/net/wifi/WifiApConfigStore.java
class WifiApConfigStore extends StateMachine {
class DefaultState extends State {
case WifiStateMachine.CMD_REQUEST_AP_CONFIG:
mReplyChannel.replyToMessage(message,
WifiStateMachine.CMD_RESPONSE_AP_CONFIG, mWifiApConfig);
break;
当前WIFI状态机状态为SoftApStartingState,所以回复消息在这里处理:
class SoftApStartingState{
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);
}
break;
case CMD_START_AP_SUCCESS:
setWifiApState(WIFI_AP_STATE_ENABLED);
transitionTo(mSoftApStartedState);
break;
private void startSoftApWithConfig(final WifiConfiguration config) {
// start hostapd on a seperate thread
new Thread(new Runnable() {
public void run() {
try {
mNwService.startAccessPoint(config, mInterfaceName);
} catch (Exception e) {
loge("Exception in softap start " + e);
try {
mNwService.stopAccessPoint(mInterfaceName);
mNwService.startAccessPoint(config, mInterfaceName);
} catch (Exception e1) {
loge("Exception in softap re-start " + e1);
sendMessage(CMD_START_AP_FAILURE);
return;
}
}
if (DBG) log("Soft AP start successful");
sendMessage(CMD_START_AP_SUCCESS);
}
}).start();
}
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mNwService = INetworkManagementService.Stub.asInterface(b);
frameworks/base/services/java/com/android/server/NetworkManagementService.java
public void startAccessPoint(
WifiConfiguration wifiConfig, String wlanIface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
wifiFirmwareReload(wlanIface, "AP"); //mConnector.execute("softap", "fwreload", wlanIface, mode); wlanIface就是prop指定的wifi.interface,默认为wlan0,mode为"AP",共计四 个参数
if (wifiConfig == null) {
mConnector.execute("softap", "set", wlanIface);
} else {
mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID, //mConnector = new NativeDaemonConnector( new NetdCallbackReceiver(), "netd", 10, NETD_TAG, 160);
getSecurityType(wifiConfig), wifiConfig.preSharedKey);
}
mConnector.execute("softap", "startap");
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
}
class InactiveState
case WifiStateMachine.CMD_SET_AP_CONFIG:
mWifiApConfig = (WifiConfiguration) message.obj;
transitionTo(mActiveState);
break;
class ActiveState extends State {
public void enter() {
new Thread(new Runnable() {
public void run() {
writeApConfiguration(mWifiApConfig);
sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED);
}
}).start();
}
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;
}
}
这里的配置文件是通过WifiManager的setWifiApConfiguration接口生成的:
public NativeDaemonEvent[] execute(int timeout, String cmd, Object... args)
throws NativeDaemonConnectorException {
final ArrayList
final int sequenceNumber = mSequenceNumber.incrementAndGet();
final StringBuilder cmdBuilder =
new StringBuilder(Integer.toString(sequenceNumber)).append(' ');
final long startTime = SystemClock.elapsedRealtime();
makeCommand(cmdBuilder, cmd, args);
final String logCmd = cmdBuilder.toString(); /* includes cmdNum, cmd, args */
log("SND -> {" + logCmd + "}");
cmdBuilder.append('\0');
final String sentCmd = cmdBuilder.toString(); /* logCmd + \0 */
synchronized (mDaemonLock) {
if (mOutputStream == null) {
throw new NativeDaemonConnectorException("missing output stream");
} else {
try {
mOutputStream.write(sentCmd.getBytes(Charsets.UTF_8));
} catch (IOException e) {
throw new NativeDaemonConnectorException("problem sending command", e);
}
}
}
NativeDaemonEvent event = null;
do {
event = mResponseQueue.remove(sequenceNumber, timeout, sentCmd);
if (event == null) {
loge("timed-out waiting for response to " + logCmd);
throw new NativeDaemonFailureException(logCmd, event);
}
log("RMV <- {" + event + "}");
events.add(event);
} while (event.isClassContinue());
final long endTime = SystemClock.elapsedRealtime();
if (endTime - startTime > WARN_EXECUTE_DELAY_MS) {
loge("NDC Command {" + logCmd + "} took too long (" + (endTime - startTime) + "ms)");
}
if (event.isClassClientError()) {
throw new NativeDaemonArgumentException(logCmd, event);
}
if (event.isClassServerError()) {
throw new NativeDaemonFailureException(logCmd, event);
}
return events.toArray(new NativeDaemonEvent[events.size()]);
}
system/netd/CommandListener.cpp
system/netd/SoftapController.cpp