android wifi frameworks层的实现由不同的版本,本版本是android 4.2,有些内容与网上所传并不雷同,比如该版本实现中没有WifiLayer类。
Android_WIFI_Frameworks层的马拉松开始了。
Wifi 连接部分
一 Wifi初始化
讲到Wifi的初始化,有必要了解Linux系统加载android的过程,该过程分为四个步骤
init进程启动-Native服务启动-SystemServer(android服务启动)-Home设定
主要关心第三步,因为这里涉及Wifi的初始化。
frameworks/base/services/java/com/android/server/SystemService.java
main()-- init1()--System_init()--init2()
<frameworks/base/services/JNI/com_android_server_systemserver.cpp>
<frameworks/base/cmds/system_server/Labrary/system_init.cpp>
init2()主要代码如下:
Thread thr = new ServerThread(); //调用构造函数
thr.setName("android.server.ServerThread");
thr.start(); //run()
run()加载服务,servicemanager.addService(..),在run()函数中注意这段代码。
try {
Slog.i(TAG, "Wi-Fi Service");
wifi = new WifiService(context);
ServiceManager.addService(Context.WIFI_SERVICE, wifi);
} catch (Throwable e) {
reportWtf("starting Wi-Fi Service", e);
}
try {
Slog.i(TAG, "Connectivity Service");
connectivity = new ConnectivityService(
context, networkManagement, networkStats, networkPolicy);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
networkStats.bindConnectivityManager(connectivity);
networkPolicy.bindConnectivityManager(connectivity);
wifi.checkAndStartWifi();
wifiP2p.connectivityServiceReady();
} catch (Throwable e) {
reportWtf("starting Connectivity Service", e);
}
第一段代码创建WifiService对象,第二段代码调用了checkAndStartWifi()方法。下面我们只需要关注WifiService类的实现了。
WifiService构造函数: mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);
checkAndStartWifi(): if (wifiEnabled) setWifiEnabled(wifiEnabled);----------------------------
//很明显,wifiEnabled为false,不能调用setWifiEnabled()函数。
到此,Wifi的初始化告一段落。
二 Wifi启动,Scan AP, 配置AP和获取IP
WifiSettings>/frameworks/base/setttings/src/com/android/setttings/wifi
在Activity显示之前调用onActivityCreated()函数
if (!mSetupWizardMode) {
mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);
}
转到WifiEnabler类
——————————————————————————————————————
CheckBox和RadioBox都是从CompoundButton中继承的,而CompoundButton是继承TextView。
<CheckBox
android:id="@+id/mycheckbox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="This checkbox is:uncheck"
/>
常用的checkcbox函数有:isChecked(),setChecked(),toggle()(改变状态,如是checked的变成unchecked,如果是unchecked变为checked。)。如果CheckBox的状态发
生更改,需要在程序中进行触发方法处理。如下:
public class HelloAndriod extends Activity implements CompoundButton.OnCheckedChangeListener{
----------------------------------------------------------------------------------------------------------------------------------
private CheckBox mycheckbox = null;
@Override
public void onCreate(Bundle savedInstanceState){
... ...
mycheckbox = (CheckBox)findViewById(R.id.mycheckbox);
mycheckbox.setOnCheckedChangeListener(this);
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
mycheckbox.setText("This checkbox is : " + (isChecked ? "checked":"unchcked"));
}
}
所以当CompoundButton状态发生改变时,调用onCheckedChanged()函数。
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mWifiManager.setWifiEnabled(isChecked)) {
// Intent has been taken into account, disable until new state is active
mSwitch.setEnabled(false);
} else {
// Error
Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
}
}
继而 mWifiManager.setWifiEnabled()-----mService.setWifiEnabled(enabled)---------mWifiStateMachine.setWifiEnabled(enable);
最终到WifiStateMachine类
public void setWifiEnabled(boolean enable) {
mLastEnableUid.set(Binder.getCallingUid());
if (enable) {
/* Argument is the state that is entered prior to load */
sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
sendMessage(CMD_START_SUPPLICANT);
} else {
sendMessage(CMD_STOP_SUPPLICANT);
/* Argument is the state that is entered upon success */
sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
}
}
而在WifiService构造函数中创建了WifiStateMachine对象,在WifiStateMachine构造函数中设置状态机初始状态为
mInitialState,如果你懂得了状态机的实现机制,
sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0))>>>>>进入mInitialState查看
mInitialState
public void enter() {
if (mWifiNative.isDriverLoaded()) {
transitionTo(mDriverLoadedState);
}
else {
transitionTo(mDriverUnloadedState);
} }
因为没有加载驱动,所以跳到mDriverUnloadedState状态,transitionTo()函数实现简单。
mDriverUnloadedState
public boolean processMessage(Message message) {
if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_LOAD_DRIVER:
transitionTo(mDriverLoadingState);
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
mDriverLoadingState
public boolean processMessage(Message message) {
if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_LOAD_DRIVER:
transitionTo(mDriverLoadingState);
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
mDriverLoadingState(enter())<在这里插一条,必须时刻关注WIFI_State_,其定义在WifiManager.java中 >
if(mWifiNative.loadDriver()) {
sendMessage(CMD_LOAD_DRIVER_SUCCESS);
} else {}
讲到这里,需要谈谈WifiNative.java了,顾名思义,本地接口
运行到文件android_net_wifi_Wifi.cpp<frameworks/base/core/Java/android/JNI>
static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
{
return (jboolean)(::wifi_unload_driver() == 0);
}
继续调用至文件wifi.c<hardware/hardware_legency/wifi.c>
int wifi_load_driver(){}
回到Frameworks层代码,如果驱动加载成功,sendMessage(CMD_LOAD_DRIVER_SUCCESS);
因为当前状态为mDriverLoadingState,回到该状态下的ProcessMessage()
switch (message.what) {
case CMD_LOAD_DRIVER_SUCCESS:
transitionTo(mDriverLoadedState);
mDriverLoadedState
到达该状态后驱动加载成功,回到先前的代码,开始执行语句sendMessage(CMD_START_SUPPLICANT);
因为当前状态为mDriverLoadedState,所以运行该状态下的processMessage>>
public boolean processMessage(Message message) {
case CMD_START_SUPPLICANT:
if(mWifiNative.startSupplicant(mP2pSupported)) {
mWifiMonitor.startMonitoring();
transitionTo(mSupplicantStartingState);
}
}
状态切换到mSupplicantStartingState,并启动mWifiMonitor监控线程,跳到startMonitoring()>>
-----------------------------------------------------------
public void startMonitoring() {
new MonitorThread().start();
}
运行到run()函数>>>>
if (connectToSupplicant()) {
mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
} else {
mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
}
因为状态机当前状态为mSupplicantStartingState,调用该状态下的processMessage>>>
switch(message.what) {
case WifiMonitor.SUP_CONNECTION_EVENT:
setWifiState(WIFI_STATE_ENABLED);
mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
mWifiInfo.setMacAddress(mWifiNative.getMacAddress());
mWifiConfigStore.initialize();
initializeWpsDetails();
sendSupplicantConnectionChangedBroadcast(true);
transitionTo(mDriverStartedState);
}
>>运行到这里,不要想当然:mSupplicantStartingState一定要切换到mSupplicantStartedState。
setWifiState(WIFI_STATE_ENABLED)跳到WifiSettings.java
mScanner.resume()// mScanner继承Handler
-----------------------------------------------------
mDriverStartedState
当有外部事件传来时,调用handlemessage()
public void handleMessage(Message message) {
if (mWifiManager.startScanActive()) {
mRetry = 0;
} else if (++mRetry >= 3) {
mRetry = 0;
Activity activity = getActivity();
if (activity != null) {
Toast.makeText(activity, R.string.wifi_fail_to_scan,
Toast.LENGTH_LONG).show();
} }
>>mWifiManager.startScanActive()>>mService.startScan(true)
public void startScan(boolean forceActive) {
enforceChangePermission();
mWifiStateMachine.startScan(forceActive);
noteScanStart();
}
主要跟踪这两个函数
1、mWifiStateMachine.startScan(forceActive)
public void startScan(boolean forceActive) {
sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
SCAN_ACTIVE : SCAN_PASSIVE, 0));
}
跳到mDriverStartedState下的processMessage()
switch(message.what) {
case CMD_START_SCAN:
boolean forceActive = (message.arg1 == SCAN_ACTIVE);
if (forceActive && !mSetScanActive) {
mWifiNative.setScanMode(forceActive);
}
mWifiNative.scan();
if (forceActive && !mSetScanActive) {
mWifiNative.setScanMode(mSetScanActive);
}
}
------------------------------------------------------------------------------------
public boolean setScanMode(boolean setActive) {
if (setActive) {
return doBooleanCommand("DRIVER SCAN-ACTIVE");
} else {
return doBooleanCommand("DRIVER SCAN-PASSIVE");
} }
public boolean scan() {
return doBooleanCommand("SCAN");
}
--------------------------------------------------------------------------------------
2、noteScanStart()
private void noteScanStart() {
WorkSource scanWorkSource = null;
synchronized (WifiService.this) {
if (mScanWorkSource != null) {
return;
}
scanWorkSource = new WorkSource(Binder.getCallingUid());
mScanWorkSource = scanWorkSource;
}
}
运行到这里,等待wpa_supplicant返回Scan结果
else if (eventName.equals(SCAN_RESULTS_STR))
event = SCAN_RESULTS;
>>>>>
void handleEvent(int event, String remainder) {
switch (event) {
case SCAN_RESULTS:
mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
break; }
}
---------------------------------------------------
运行到这里,因为当前状态为mDriverStartedState,你是否会去找该状态下的processMessage()
没错,你方向是对的,但是为什么processMessage()中没有处理SCAN_RESULTS_EVENT事件
的case语句,因为处理该事件的case语句包含在mSupplicantStartedState的processMessage()函数
中,参考状态机的实现机制。
---------------------------------
case WifiMonitor.SCAN_RESULTS_EVENT:
setScanResults(mWifiNative.scanResults());
if (!mhasCMCCSavedToConfig) {
WifiConfiguration wc = fetchConfigFromScanResults("CMCC");
sendScanResultsAvailableBroadcast();
mScanResultIsPending = false;
}break;
}
这段代码中涉及CMCC,留待下面的环节细看
>>>>sendScanResultsAvailableBroadcast()
>>>
private void sendScanResultsAvailableBroadcast() {
Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
>>>wifiSettings.java
updateAccessPoints();
switch (wifiState) {
case WifiManager.WIFI_STATE_ENABLED:
final Collection<AccessPoint> accessPoints = constructAccessPoints();
Log.d(TAG, "remove all preference");
getPreferenceScreen().removeAll();
if(accessPoints.size() == 0) {
addMessagePreference(R.string.wifi_empty_list_wifi_on);
}
for (AccessPoint accessPoint : accessPoints) {
Log.d(TAG, "add preference accessPoint = " + accessPoint);
getPreferenceScreen().addPreference(accessPoint);
}
break;
}
配置ap参数>>>当用户点击某一个ap时出现ap配置对话框
private void showDialog(AccessPoint accessPoint, boolean edit) {
Log.d(TAG, "Enter showDialog edit = " + edit + " accessPoint = " + accessPoint);
if (mDialog != null) {
Log.d(TAG, "remove WIFI_DIALOG");
removeDialog(WIFI_DIALOG_ID);
mDialog = null;
}
mDlgAccessPoint = accessPoint;
mDlgEdit = edit;
showDialog(WIFI_DIALOG_ID);
}
连接ap>>>>>>>>connectDuetoAutoConnectMode()
private void connectDuetoAutoConnectMode(WifiConfiguration config, WifiManager.ActionListener listener) {
if (!mAutoConnect) {
mWifiManager.enableNetwork(INVALID_NETWORK_ID, true);
}
mWifiManager.connect(config, listener);
}
mWifiManager.enableNetwork()>>>>mWifiService.enableNetwork()
>>>mWifiStateMachine.syncenableNetwork()
public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
disableOthers ? 1 : 0);
}
>>mSupplicantStartedState的processMessage()
>> case CMD_ENABLE_NETWORK:
ok = mWifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
break;
>> mWifiConfigStore.enableNetwork()
boolean enableNetwork(int netId, boolean disableOthers) {
boolean ret = enableNetworkWithoutBroadcast(netId, disableOthers);
if (disableOthers) {
sendConfiguredNetworksChangedBroadcast();
} else {
WifiConfiguration enabledNetwork = null;
synchronized(mConfiguredNetworks) {
enabledNetwork = mConfiguredNetworks.get(netId);
}
if (enabledNetwork != null) {
sendConfiguredNetworksChangedBroadcast(enabledNetwork,
WifiManager.CHANGE_REASON_CONFIG_CHANGE);
}
}
>>> enableNetworkWithoutBroadcast()
>>
boolean enableNetworkWithoutBroadcast(int netId, boolean disableOthers) {
boolean ret = mWifiNative.enableNetwork(netId, disableOthers);
WifiConfiguration config = mConfiguredNetworks.get(netId);
}
>>>mWifiNative.enableNetwork()
---------------------------------------------------------------------------------------
接下来很重要的一步就是启动DHCP分配IP地址
ObtainingIpState
>>enter()
>>>
mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
>>>跳到frameworks/base/core/java/net/DHCP/DhcpStateMachine.java
>>> 该状态机初始状态为StoppedState
switch (message.what) {
case CMD_START_DHCP:
if (mRegisteredForPreDhcpNotification) {
mController.sendMessage(CMD_PRE_DHCP_ACTION);
transitionTo(mWaitBeforeStartState);
}
>>>>>跳到WifiStateMachine.java
>>因为mL2ConnectedState是mObtainingIpState的父亲,调用
mL2ConnectedState中的processMessage()
>>>
switch (message.what) {
case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
handlePreDhcpSetup();
mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
break;
}
>>>跳到frameworks/base/core/java/net/DHCP/DhcpStateMachine.java
该状态机当前状态为WaitBeforeStartState,执行该状态下的processMessage()
>>>
switch (message.what) {
case CMD_PRE_DHCP_ACTION_COMPLETE:
if (runDhcp(DhcpAction.START)) {
transitionTo(mRunningState);}
>>>runDhcp()>>NetworkUtils.runDhcp()
private boolean runDhcp(DhcpAction dhcpAction) {
boolean success = false;
DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
if (dhcpAction == DhcpAction.START) {
if (DBG) Log.d(TAG, "DHCP request on " + mInterfaceName);
success = NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal);
mDhcpInfo = dhcpInfoInternal;
}
//framework/base/core/jni/android_net_NetUtils.cpp
接下来就是调用底层代码了,启动DHCP后就可以分配IP地址了
还有些东西没有贴出,如需进一步了解,请加QQ:398024684