android中wifi原理及流程分析

来源:互联网 发布:微信小程序 php服务端 编辑:程序博客网 时间:2024/05/21 17:10

wifi相关的文件位置:

WIFI Settings应用程序位于

       packages/apps/Settings/src/com/android/settings/wifi/

JAVA部分:

        frameworks/base/services/java/com/android/server/

        frameworks/base/wifi/java/android/net/wifi/

JNI部分:

       frameworks/base/core/jni/android_net_wifi_Wifi.cpp

wifi管理库。

        hardware/libhardware_legary/wifi/

 wifi用户空间的程序和库:

        external/wpa_supplicant/

       生成库libwpaclient.so和守护进程wpa_supplicant。

 

调用流程:

wifi模块的初始化:

(frameworks/base/services/java/com/android/server/SystemServer.Java)

在 SystemServer 启动的时候,会生成一个ConnectivityService 的实例,

classServerThread extends Thread {

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。        

  try {                Slog.i(TAG,"Connectivity Service");                connectivity= ConnectivityService.getInstance(context);               ServiceManager.addService(Context.CONNECTIVITY_SERVICE,connectivity);            } catch(Throwable e) {                Slog.e(TAG,"Failure starting Connectivity Service", e);            }。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。}


 

其中 ,ConnectivityService.getInstance(context);  对应于(frameworks/base/services/java/com/android/server/ConnectivityService.JavaConnectivityService.Java。

下面看下ConnectivityService.Java中的  

 

public static ConnectivityServicegetInstance(Context context) {       return ConnectivityThread.getServiceInstance(context);   }函数, 继续往下看:       public static ConnectivityService getServiceInstance(Context context) {           ConnectivityThread thread = newConnectivityThread(context);            thread.start();           synchronized (thread) {               while (sServiceInstance == null) {                    try {                        // Wait until sServiceInstance has beeninitialized.                        thread.wait();                    } catch (InterruptedExceptionignore) {                        Slog.e(TAG,                            "UnexpectedInterruptedException while waiting"+                            " forConnectivityService thread");                    }               }           }            return sServiceInstance;        }    }

继续往下跟:

private static class ConnectivityThread extends Thread {       private Context mContext;        private ConnectivityThread(Context context) {           super("ConnectivityThread");           mContext = context;        }       @Override        public void run() {           Looper.prepare();           synchronized (this) {               sServiceInstance = newConnectivityService(mContext);               notifyAll();           }            Looper.loop();        }       public static ConnectivityService getServiceInstance(Context context) {           ConnectivityThread thread = new ConnectivityThread(context);           thread.start();           synchronized (thread) {                while (sServiceInstance == null) {                    try {                        // Wait untilsServiceInstance has been initialized.                        thread.wait();                    } catch(InterruptedException ignore) {                        Slog.e(TAG,                            "UnexpectedInterruptedException while waiting"+                            " forConnectivityService thread");                    }               }           }           return sServiceInstance;        }    }


继续newConnectivityService(mContext)

private ConnectivityService(Context context) {。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。    for(int netType : mPriorityList) {           switch (mNetAttributes[netType].mRadio) {           case ConnectivityManager.TYPE_WIFI:               Slog.v(TAG, "Starting Wifi Service.");               WifiStateTracker wst = newWifiStateTracker(context, mHandler);               WifiService wifiService = newWifiService(context, wst);               ServiceManager.addService(Context.WIFI_SERVICE,wifiService);               wifiService.startWifi();//启动wifiservice               mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;               wst.startMonitoring();//启动Monitoring                break;   。。。。。          }//endfor。。。。。。。。。。。。。。。。。。。。。。。。。。}

到这里模块初始化的工作完成,具体流程图如下:


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

也就是说WifiService负责wifi整个流程的控制,而WifiMonitor负责监视底层的事件。

此时WifiService starting up withWi-Fi disabled,

 

Wifi模块的启动(Enable):

packages/apps/Settings/src/com/android/settings/wifi/ WirelessSettings.java

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

 protected void onCreate(BundlesavedInstanceState) {        super.onCreate(savedInstanceState);         mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);         if (getIntent().getBooleanExtra("only_access_points",false)) {           addPreferencesFromResource(R.xml.wifi_access_points);        } else {           addPreferencesFromResource(R.xml.wifi_settings);            mWifiEnabler = new WifiEnabler(this,                    (CheckBoxPreference)findPreference("enable_wifi"));            mNotifyOpenNetworks =                    (CheckBoxPreference)findPreference("notify_open_networks");           mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(),                    Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,0) == 1);        }         mAccessPoints = (ProgressCategory)findPreference("access_points");       mAccessPoints.setOrderingAsAdded(false);        mAddNetwork =findPreference("add_network");         registerForContextMenu(getListView());    }

然后调用:packages/apps/Settings/src/com/android/settings/wifi/ WifiEnabler.java)

2012-03-26  jemeen  摘自 csdn博客  阅 4092  转 39转藏到我的图书馆微信分享:在网上找的一篇好文章,分析的很详细,自己再加了些东西,图片有点大,不能完全显示,点击图像拖动鼠标直接查看图像。wifi相关的文件位置:WIFI Settings应用程序位于       packages/apps/Settings/src/com/android/settings/wifi/JAVA部分:        frameworks/base/services/java/com/android/server/        frameworks/base/wifi/java/android/net/wifi/JNI部分:       frameworks/base/core/jni/android_net_wifi_Wifi.cppwifi管理库。        hardware/libhardware_legary/wifi/ wifi用户空间的程序和库:        external/wpa_supplicant/       生成库libwpaclient.so和守护进程wpa_supplicant。 调用流程:wifi模块的初始化:(frameworks/base/services/java/com/android/server/SystemServer.Java)在 SystemServer 启动的时候,会生成一个ConnectivityService 的实例,classServerThread extends Thread {。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。           try {                Slog.i(TAG,"Connectivity Service");                connectivity= ConnectivityService.getInstance(context);               ServiceManager.addService(Context.CONNECTIVITY_SERVICE,connectivity);            } catch(Throwable e) {                Slog.e(TAG,"Failure starting Connectivity Service", e);            }。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。} 其中 ,ConnectivityService.getInstance(context);  对应于(frameworks/base/services/java/com/android/server/ ConnectivityService.Java)ConnectivityService.Java。下面看下ConnectivityService.Java中的   public static ConnectivityServicegetInstance(Context context) {       return ConnectivityThread.getServiceInstance(context);   }函数, 继续往下看:       public static ConnectivityService getServiceInstance(Context context) {           ConnectivityThread thread = newConnectivityThread(context);            thread.start();           synchronized (thread) {               while (sServiceInstance == null) {                    try {                        // Wait until sServiceInstance has beeninitialized.                        thread.wait();                    } catch (InterruptedExceptionignore) {                        Slog.e(TAG,                            "UnexpectedInterruptedException while waiting"+                            " forConnectivityService thread");                    }               }           }            return sServiceInstance;        }    }继续往下跟:private static class ConnectivityThread extends Thread {       private Context mContext;        private ConnectivityThread(Context context) {           super("ConnectivityThread");           mContext = context;        }       @Override        public void run() {           Looper.prepare();           synchronized (this) {               sServiceInstance = newConnectivityService(mContext);               notifyAll();           }            Looper.loop();        }       public static ConnectivityService getServiceInstance(Context context) {           ConnectivityThread thread = new ConnectivityThread(context);           thread.start();           synchronized (thread) {                while (sServiceInstance == null) {                    try {                        // Wait untilsServiceInstance has been initialized.                        thread.wait();                    } catch(InterruptedException ignore) {                        Slog.e(TAG,                            "UnexpectedInterruptedException while waiting"+                            " forConnectivityService thread");                    }               }           }           return sServiceInstance;        }    }继续newConnectivityService(mContext)private ConnectivityService(Context context) {。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。    for(int netType : mPriorityList) {           switch (mNetAttributes[netType].mRadio) {           case ConnectivityManager.TYPE_WIFI:               Slog.v(TAG, "Starting Wifi Service.");               WifiStateTracker wst = newWifiStateTracker(context, mHandler);               WifiService wifiService = newWifiService(context, wst);               ServiceManager.addService(Context.WIFI_SERVICE,wifiService);               wifiService.startWifi();//启动wifiservice               mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;               wst.startMonitoring();//启动Monitoring                break;   。。。。。          }//endfor。。。。。。。。。。。。。。。。。。。。。。。。。。}到这里模块初始化的工作完成,具体流程图如下: WifiStateTracker 会创建 WifiMonitor 接收来自底层的事件, WifiService 和 WifiMonitor 是整个模块的核心。WifiService 负责启动关闭 wpa_supplicant、启动关闭 WifiMonitor 监视线程和把命令下发给 wpa_supplicant,而 WifiMonitor 则负责从 wpa_supplicant 接收事件通知。也就是说WifiService负责wifi整个流程的控制,而WifiMonitor负责监视底层的事件。此时WifiService starting up withWi-Fi disabled, Wifi模块的启动(Enable): (packages/apps/Settings/src/com/android/settings/wifi/ WirelessSettings.java)WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮,    protected void onCreate(BundlesavedInstanceState) {        super.onCreate(savedInstanceState);         mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);         if (getIntent().getBooleanExtra("only_access_points",false)) {           addPreferencesFromResource(R.xml.wifi_access_points);        } else {           addPreferencesFromResource(R.xml.wifi_settings);            mWifiEnabler = new WifiEnabler(this,                    (CheckBoxPreference)findPreference("enable_wifi"));            mNotifyOpenNetworks =                    (CheckBoxPreference)findPreference("notify_open_networks");           mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(),                    Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,0) == 1);        }         mAccessPoints = (ProgressCategory)findPreference("access_points");       mAccessPoints.setOrderingAsAdded(false);        mAddNetwork =findPreference("add_network");         registerForContextMenu(getListView());    } 然后调用:(packages/apps/Settings/src/com/android/settings/wifi/ WifiEnabler.java)publicclass WifiEnabler implements Preference.OnPreferenceChangeListener {。。。。。。。。。。。。。。。。。。。。。。   public boolean onPreferenceChange(Preferencepreference, Object value) {。。。。。。。。。。。。。。。。。。。。。。。。。。。        if (mWifiManager.setWifiEnabled(enable)){            mCheckBox.setEnabled(false);        } else {           mCheckBox.setSummary(R.string.wifi_error);        }。。。。。。。。。。。。。。。。。。。。。。        }。。。。。。。。。。。。。。。。。。。。。}


调用:

packages/apps/Settings/src/com/android/settings/wifi/WifiManager.java)

 public boolean setWifiEnabled(booleanenabled) {        try {            returnmService.setWifiEnabled(enabled);        } catch(RemoteException e) {            returnfalse;        }    }


当用户按下 Wifi 按钮后,  Android 会调用 WifiEnabler 的onPreferenceChange,  再由 WifiEnabler调用 WifiManager 的setWifiEnabled 接口函数,通过 AIDL,实际调用的是 WifiService 的setWifiEnabled 函数,WifiService 接着向自身发送一条 MESSAGE_ENABLE_WIFI 消息,在处理该消息的代码中做真正的使能工作:首先装载 WIFI 内核模块(该模块的位置硬编码为"/system/lib/modules/wlan.ko" ), 然 后 启 动 wpa_supplicant ( 配 置 文 件 硬 编 码 为"/data/misc/wifi/wpa_supplicant.conf")再通过 WifiStateTracker 来启动 WifiMonitor 中的监视线程。

WifiService(WifiService.java) 收到MESSAGE_ENABLE_WIFI 消息后的操作如下:

AIDL:

Android Interface Definition Language,即Android接口描述语言。Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。

为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(InterfaceDefinition Language,IDL)来公开服务的接口。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。


接下来继续道wifiService.Java

(frameworks/base/services/java/com/android/server/ wifiService.Java


 public boolean setWifiEnabled(boolean enable) {        enforceChangePermission();        if (mWifiHandler == null) return false;         synchronized (mWifiHandler) {            // caller may not have WAKE_LOCKpermission - it's not required here            long ident =Binder.clearCallingIdentity();            sWakeLock.acquire();           Binder.restoreCallingIdentity(ident);             mLastEnableUid =Binder.getCallingUid();            // set a flag if the user isenabling Wifi while in airplane mode            mAirplaneModeOverwridden = (enable&& isAirplaneModeOn() && isAirplaneToggleable());            sendEnableMessage(enable, true,Binder.getCallingUid());  //  here send a mesage to himself        }        return true;    }继续往下:    private void sendEnableMessage(boolean enable,boolean persist, int uid) {        Message msg= Message.obtain(mWifiHandler,                                     (enable ?MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),                                     (persist ? 1 : 0), uid);        msg.sendToTarget();    }WifiHandler会收到消息:private class WifiHandlerextends Handler {。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。public voidhandleMessage(Message msg) {            switch (msg.what) {                case MESSAGE_ENABLE_WIFI:                    setWifiEnabledBlocking(true, msg.arg1 == 1,msg.arg2);                    if (mWifiWatchdogService ==null) {                        mWifiWatchdogService = newWifiWatchdogService(mContext, mWifiStateTracker);                    }                    sWakeLock.release();                    break;。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。                  }。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。}privateboolean setWifiEnabledBlocking(booleanenable, boolean persist, int uid) {。。。。。。。。。。。。  setWifiEnabledState(enable ?WIFI_STATE_ENABLING : WIFI_STATE_DISABLING, uid); if (enable) {            if (!mWifiStateTracker.loadDriver()){                Slog.e(TAG, "Failed toload Wi-Fi driver.");               setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);                return false;            }            if (!mWifiStateTracker.startSupplicant()){               mWifiStateTracker.unloadDriver();                Slog.e(TAG, "Failed tostart supplicant daemon.");               setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);                return false;            }             registerForBroadcasts();            mWifiStateTracker.startEventLoop();         } else {            mContext.unregisterReceiver(mReceiver);           // Remove notification (it willno-op if it isn't visible)            mWifiStateTracker.setNotificationVisible(false,0, false, 0);             booleanfailedToStopSupplicantOrUnloadDriver = false;             if (!mWifiStateTracker.stopSupplicant()){                Slog.e(TAG, "Failed tostop supplicant daemon.");                setWifiEnabledState(WIFI_STATE_UNKNOWN,uid);               failedToStopSupplicantOrUnloadDriver = true;            }             /**             * Reset connections and disableinterface             * before we unload the driver             */            mWifiStateTracker.resetConnections(true);             if (!mWifiStateTracker.unloadDriver()){                Slog.e(TAG, "Failed tounload Wi-Fi driver.");                if(!failedToStopSupplicantOrUnloadDriver) {                    setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);                   failedToStopSupplicantOrUnloadDriver = true;                }            }             if(failedToStopSupplicantOrUnloadDriver) {                return false;            }        }。。。。。。。。。。。。。。。。。。。。。。}




扫描查找热点(AP)

上一节中讲到Wifi模块开启后会对外发送WIFI_STATE_CHANGED_ACTION。WifiLayer中注册了Action的Receiver。
当WifiLayer收到此Action后开始scan的流程,具体如下:


当wpa_supplicant 处理完SCAN 命令后,它会向控制通道发送事件通知扫描完成,从wifi_wait_for_event函数会接收到该事件,由此WifiMonitor 中的MonitorThread会被执行来出来这个事件:


配置 AP 参数
当用户在WifiSettings 界面上选择了一个AP 后,会显示配置AP 参数的一个对话框:


Wifi连接

具体流程参见以下流程图:




IP地址的配置
流程如图:




                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  end ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0 0
原创粉丝点击