您的位置:首页 > 其它

WIFI操作流程源码分析—启动

2014-02-26 14:38 148 查看
WIFI操作流程源码分析—启动
初始化

在 SystemServer
启动的时候,会生成WifiService和ConnectivityService
的实例,在SystemServer.java中

try {

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);

}

在ConnectivityService.java中构造函数ConnectivityService中创建DefaultNetworkFactory对象

public ConnectivityService(Context context, INetworkManagementService netManager,

INetworkStatsService statsService, INetworkPolicyManager policyManager,

NetworkFactory netFactory) {

if (netFactory == null) {

netFactory = new DefaultNetworkFactory(context, mTrackerHandler);

}

}

在DefaultNetworkFactory.java中创建类WifiStateTracker对象

private static class DefaultNetworkFactory implements NetworkFactory {

@Override

public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config) {

switch (config.radio) {

case TYPE_WIFI:

return new WifiStateTracker(targetNetworkType, config.name);

}

}

}

ConnectivityService 的构造函数会创建 mWifiStateTracker,而WifiStateTracker会创建 WifiMonitor
接收来自底层的事件,WifiService和 WifiMonitor
是整个模块的核心。WifiService负责启动关闭 wpa_supplicant、启动关闭 WifiMonitor监视线程和把命令下发给 wpa_supplicant,而
WifiMonitor则负责从 wpa_supplicant 接收事件通知。

使能 WIFI

WifiSettings 在初始化的时候onActivityCreated配置了由 WifiEnabler来处理 Wifi
按钮,

@Override

public void onActivityCreated(Bundle savedInstanceState) {

Switch actionBarSwitch = new Switch(activity);

mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);

}

当用户按下 Wifi
切换按钮后,Android 会调用 WifiEnabler的 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();

}

}

再由 WifiEnabler调用 WifiManager的 setWifiEnabled
接口函数,

public boolean setWifiEnabled(boolean enabled) {

try {

return mService.setWifiEnabled(enabled);

} catch (RemoteException e) {

return false;

}

}

通过 AIDL,实际调用的是 WifiService的setWifiEnabled
函数,

public synchronized boolean setWifiEnabled(boolean enable) {

Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()

+ ", uid=" + Binder.getCallingUid());

enforceChangePermission();

mAirplaneModeOn.set(isAirplaneModeOn());

if (mWifiStateMachine.hasCustomizedAutoConnect() && enable && mAirplaneModeOn.get()) {

SXlog.i(TAG, "Can't enable wifi when airplane mode is on for customization.");

return false;

}

if (DBG) {

Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");

}

if (enable) {

reportStartWorkSource();

}

mWifiStateMachine.setWifiEnabled(enable);

/*

* Caller might not have WRITE_SECURE_SETTINGS,

* only CHANGE_WIFI_STATE is enforced

*/

long ident = Binder.clearCallingIdentity();

try {

handleWifiToggled(enable);

} finally {

Binder.restoreCallingIdentity(ident);

}

if (enable) {

if (!mIsReceiverRegistered) {

registerForBroadcasts();

mIsReceiverRegistered = true;

}

} else if (mIsReceiverRegistered) {

mContext.unregisterReceiver(mReceiver);

mIsReceiverRegistered = false;

}

return true;

}

WifiService 接着通过WifiStateMachine中函数setWifiEnabled发送WIFI_STATE_ENABLING消息,

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));

}

}

它做了两个动作,向状态机发送了2个消息

sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));加载驱动

sendMessage(CMD_START_SUPPLICANT);开启supplicant

加载驱动

状态机构造函数初始化时候,设置有个一个初始状态

setInitialState(mInitialState);

我们进入mInitialState状态看看

public void enter() {

if (WifiNative.isDriverLoaded()) {

transitionTo(mDriverLoadedState);

}

else {

transitionTo(mDriverUnloadedState);

}

因为最开始驱动都是没有加载的,所以进入transitionTo(mDriverUnloadedState);

transitionTo函数是状态切换的函数。

DriverUnloadedState类如下:

class DriverUnloadedState extends State {

@Override

public boolean processMessage(Message message) {

switch (message.what) {

case CMD_LOAD_DRIVER:

mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING);

transitionTo(mWaitForP2pDisableState);

break;

case WifiP2pService.P2P_ENABLE_PENDING:

mReplyChannel.replyToMessage(message, P2P_ENABLE_PROCEED);

break;

default:

return NOT_HANDLED;

}

EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);

return HANDLED;

}

}

这里会处理刚才的CMD_LOAD_DRIVER这个消息,继续切换到mWaitForP2pDisableState

class WaitForP2pDisableState extends State {

@Override

public boolean processMessage(Message message) {

if (DBG) log(getName() + message.toString() + "\n");

switch(message.what) {

case WifiP2pService.WIFI_ENABLE_PROCEED:

//restore argument from original message (CMD_LOAD_DRIVER)

message.arg1 = mSavedArg;

transitionTo(mDriverLoadingState);

break;

}

状态继续切换到mDriverLoadingState。

这里回调用WifiNative.loadDriver()加载驱动,成功后发送消息CMD_LOAD_DRIVER_SUCCESS,否则CMD_LOAD_DRIVER_FAILURE,

static JNINativeMethod gWifiMethods[] = {

/* name, signature, funcPtr */

{ "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },

};

由此可知会进入JNI

static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)

{

return (jboolean)(::wifi_load_driver() == 0);

}

继续到wifi.c处理

int wifi_load_driver()

{

#ifdef WIFI_DRIVER_MODULE_PATH

char driver_status[PROPERTY_VALUE_MAX];

int count = 100; /* wait at most 20 seconds for completion */

int status = -1;

if (is_wifi_driver_loaded()) {

return 0;

}

/* ensure that wlan driver config file exists (if specified) */

if (ensure_wlan_driver_config_file_exists()) {

return -1;

}

property_set(DRIVER_PROP_NAME, "loading");

if(system(SDIO_POLLING_ON))

LOGW("Couldn't turn on SDIO polling: %s", SDIO_POLLING_ON);

if ('\0' != *DRIVER_SDIO_IF_MODULE_PATH) {

if (insmod(DRIVER_SDIO_IF_MODULE_PATH, DRIVER_SDIO_IF_MODULE_ARG) < 0) {

goto end;

}

}

if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) {

if ('\0' != *DRIVER_SDIO_IF_MODULE_NAME) {

rmmod(DRIVER_SDIO_IF_MODULE_NAME);

}

goto end;

}

if (strcmp(FIRMWARE_LOADER,"") == 0) {

/* usleep(WIFI_DRIVER_LOADER_DELAY); */

property_set(DRIVER_PROP_NAME, "ok");

}

else {

property_set("ctl.start", FIRMWARE_LOADER);

}

sched_yield();

while (count-- > 0) {

if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {

if (strcmp(driver_status, "ok") == 0) {

status = 0;

goto end;

}

else if (strcmp(driver_status, "failed") == 0) {

_wifi_unload_driver();

goto end;

}

}

usleep(200000);

}

property_set(DRIVER_PROP_NAME, "timeout");

wifi_unload_driver();

end:

system(SDIO_POLLING_OFF);

return status;

#else

property_set(DRIVER_PROP_NAME, "ok");

return 0;

#endif

}

这里有几个比较重要的宏

#define WIFI_DRIVER_MODULE_PATH "/system/lib/modules/wlan.ko"驱动模块地址

static const char SUPP_CONFIG_FILE[] = "/data/misc/wifi/wpa_supplicant.conf"; supplicant配置文件

在这里wifi.c会跟wpa_supplicant通信,加载驱动

开启supplicant

另一个消息sendMessage(CMD_START_SUPPLICANT);在DriverLoadedState处理

class DriverLoadedState extends State {

@Override

public boolean processMessage(Message message) {

case CMD_START_SUPPLICANT:

try {

mNwService.wifiFirmwareReload(mInterfaceName, "STA");

} catch (Exception e) {

loge("Failed to reload STA firmware " + e);

// continue

}

try {

mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);

} catch (RemoteException re) {

loge("Unable to change interface settings: " + re);

} catch (IllegalStateException ie) {

loge("Unable to change interface settings: " + ie);

}

if(WifiNative.startSupplicant()) {

if (DBG) log("Supplicant start successful");

mWifiMonitor.startMonitoring();

transitionTo(mSupplicantStartingState);

} else {

loge("Failed to start supplicant!");

sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));

}

break;

继续调用JNI,WifiNative.startSupplicant(),过程差不多最后在wifi.c处理

int wifi_start_supplicant()

{

return wifi_start_supplicant_common(SUPP_CONFIG_FILE);

}

int wifi_start_supplicant_common(const char *config_file)

最后也是在这里跟Wpa_supplicant驱动通信

WIFI状态切换

在wifi状态发生改变的时候,wifistatemachine会通过setwifistate发送WIFI_STATE_CHANGED_ACTION消息通知外面

private void setWifiState(int wifiState) {

final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);

intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);

intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);

intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);

mContext.sendStickyBroadcast(intent);

}

例如在驱动加载状态

class DriverLoadingState extends State {

new Thread(new Runnable() {

public void run() {

mWakeLock.acquire();

//enabling state

switch(message.arg1) {

case WIFI_STATE_ENABLING:

setWifiState(WIFI_STATE_ENABLING);

break;

case WIFI_AP_STATE_ENABLING:

setWifiApState(WIFI_AP_STATE_ENABLING);

break;

}

}

在wifisettings里面也有广播监听器

public WifiSettings() {

mFilter = new IntentFilter();

mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);

mReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

handleEvent(context, intent);

}

};

mScanner = new Scanner();

}

当接受到广播会相应处理handleEvent

private void handleEvent(Context context, Intent intent) {

String action = intent.getAction();

if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {

updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,

WifiManager.WIFI_STATE_UNKNOWN));

}

}

更新wifi状态

private void updateWifiState(int state) {

getActivity().invalidateOptionsMenu();

switch (state) {

case WifiManager.WIFI_STATE_ENABLED:

mScanner.resume();

return; // not break, to avoid the call to pause() below

case WifiManager.WIFI_STATE_ENABLING:

addMessagePreference(R.string.wifi_starting);

break;

case WifiManager.WIFI_STATE_DISABLED:

addMessagePreference(R.string.wifi_empty_list_wifi_off);

break;

}

}

比如 case WifiManager.WIFI_STATE_ENABLED:当WIFI可用通知接受到的时候

mScanner.resume();

Scanner resume函数

void resume() {

if (!hasMessages(0)) {

sendEmptyMessage(0);

}

}

处理函数如下:

@Override

public void handleMessage(Message message) {

if (mWifiManager.startScanActive()) {

mRetry = 0;

} else if (++mRetry >= 3) {

mRetry = 0;

Toast.makeText(getActivity(), R.string.wifi_fail_to_scan,

Toast.LENGTH_LONG).show();

return;

}

sendEmptyMessageDelayed(0, WIFI_RESCAN_INTERVAL_MS);

}

}

会调用mWifiManager.startScanActive()进行ap的扫描。

所以当你点击wifi按钮,到驱动加载完成,发出WIFI_STATE_ENABLED消息的时候,wifi已经启动。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: