一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

android中wifi原理及流程分析(很經(jīng)典)

 jemeen 2012-03-26

在網(wǎng)上找的一篇好文章,分析的很詳細(xì),自己再加了些東西,圖片有點(diǎn)大,不能完全顯示,點(diǎn)擊圖像拖動(dòng)鼠標(biāo)直接查看圖像。

wifi相關(guān)的文件位置:

WIFI Settings應(yīng)用程序位于

       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和守護(hù)進(jìn)程wpa_supplicant。

 

調(diào)用流程:

wifi模塊的初始化:

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

在 SystemServer 啟動(dòng)的時(shí)候,會(huì)生成一個(gè)ConnectivityService 的實(shí)例,

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);  對(duì)應(yīng)于(frameworks/base/services/java/com/android/server/ ConnectivityService.JavaConnectivityService.Java。

下面看下ConnectivityService.Java中的  

 public static ConnectivityServicegetInstance(Context context) {

       return ConnectivityThread.getServiceInstance(context);

   }函數(shù), 繼續(xù)往下看:

       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;

        }

    }

繼續(xù)往下跟:

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;

        }

    }

繼續(xù)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();//啟動(dòng)wifiservice

               mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;

               wst.startMonitoring();//啟動(dòng)Monitoring

 

               break;   。。。。。

          }//endfor

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

}


到這里模塊初始化的工作完成,具體流程圖如下:

 

WifiStateTracker 會(huì)創(chuàng)建 WifiMonitor 接收來自底層的事件, WifiService 和 WifiMonitor 是整個(gè)模塊的核心。WifiService 負(fù)責(zé)啟動(dòng)關(guān)閉 wpa_supplicant、啟動(dòng)關(guān)閉 WifiMonitor 監(jiān)視線程和把命令下發(fā)給 wpa_supplicant,而 WifiMonitor 則負(fù)責(zé)從 wpa_supplicant 接收事件通知。

也就是說WifiService負(fù)責(zé)wifi整個(gè)流程的控制,而WifiMonitor負(fù)責(zé)監(jiān)視底層的事件。

此時(shí)WifiService starting up withWi-Fi disabled,

 

Wifi模塊的啟動(dòng)(Enable):

 

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

WirelessSettings 在初始化的時(shí)候配置了由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());

    }

 

然后調(diào)用: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);

        }

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

        }

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

}

 

調(diào)用:

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

    public boolean setWifiEnabled(booleanenabled) {

        try {

            returnmService.setWifiEnabled(enabled);

        } catch(RemoteException e) {

            returnfalse;

        }

    }

 

      當(dāng)用戶按下 Wifi 按鈕后,  Android 會(huì)調(diào)用 WifiEnabler 的onPreferenceChange,  再由 WifiEnabler調(diào)用 WifiManager 的 setWifiEnabled 接口函數(shù),通過 AIDL,實(shí)際調(diào)用的是 WifiService 的setWifiEnabled 函數(shù),WifiService 接著向自身發(fā)送一條 MESSAGE_ENABLE_WIFI 消息,在處理該消息的代碼中做真正的使能工作:首先裝載 WIFI 內(nèi)核模塊(該模塊的位置硬編碼為"/system/lib/modules/wlan.ko" ), 然 后 啟 動(dòng) wpa_supplicant ( 配 置 文 件 硬 編 碼 為"/data/misc/wifi/wpa_supplicant.conf")再通過 WifiStateTracker 來啟動(dòng) WifiMonitor 中的監(jiān)視線程。

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

AIDL:

Android Interface Definition Language,即Android接口描述語言。Android系統(tǒng)中的進(jìn)程之間不能共享內(nèi)存,因此,需要提供一些機(jī)制在不同進(jìn)程之間進(jìn)行數(shù)據(jù)通信。

為了使其他的應(yīng)用程序也可以訪問本應(yīng)用程序提供的服務(wù),Android系統(tǒng)采用了遠(yuǎn)程過程調(diào)用(Remote Procedure Call,RPC)方式來實(shí)現(xiàn)。與很多其他的基于RPC的解決方案一樣,Android使用一種接口定義語言(InterfaceDefinition Language,IDL)來公開服務(wù)的接口。因此,可以將這種可以跨進(jìn)程訪問的服務(wù)稱為AIDL(Android Interface Definition Language)服務(wù)。

 

接下來繼續(xù)道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;

    }

繼續(xù)往下:

    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會(huì)收到消息:

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;

            }

        }

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

}

具體流程如下流程圖所示:



 

 

掃描查找熱點(diǎn)(AP)

上一節(jié)中講到Wifi模塊開啟后會(huì)對(duì)外發(fā)送WIFI_STATE_CHANGED_ACTION。WifiLayer中注冊(cè)了Action的Receiver。
當(dāng)WifiLayer收到此Action后開始scan的流程,具體如下:


 

當(dāng)wpa_supplicant 處理完SCAN 命令后,它會(huì)向控制通道發(fā)送事件通知掃描完成,從wifi_wait_for_event函數(shù)會(huì)接收到該事件,由此WifiMonitor 中的MonitorThread會(huì)被執(zhí)行來出來這個(gè)事件:


 

 

配置 AP 參數(shù)
當(dāng)用戶在WifiSettings 界面上選擇了一個(gè)AP 后,會(huì)顯示配置AP 參數(shù)的一個(gè)對(duì)話框:


 

 

Wifi連接

具體流程參見以下流程圖:



 

IP地址的配置
流程如圖:


到此結(jié)束。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    婷婷基地五月激情五月| 日韩亚洲精品国产第二页| 日韩一级一片内射视频4k| 国产精品激情在线观看| 亚洲一区二区三在线播放| 欧美一区二区三区视频区| 日本高清一区免费不卡| 国产又粗又猛又大爽又黄同志| 91亚洲精品亚洲国产| 老熟女露脸一二三四区| 91欧美激情在线视频| 97人妻精品一区二区三区男同| 99久久人妻中文字幕| 欧美一区二区三区高潮菊竹| 国产欧美日韩视频91| 激情亚洲内射一区二区三区| 久热香蕉精品视频在线播放| 亚洲欧美中文日韩综合| 最新69国产精品视频| 欧美一区二区三区五月婷婷| 免费观看日韩一级黄色大片| 麻豆91成人国产在线观看| 中文字幕一二区在线观看| 久久香蕉综合网精品视频| 国产高清精品福利私拍| 国产亚洲精品久久久优势| 日本不卡在线视频你懂的| 91蜜臀精品一区二区三区| 91在线爽的少妇嗷嗷叫| 黄片免费观看一区二区| 精品国产91亚洲一区二区三区| 亚洲午夜av一区二区| 国产精品内射视频免费| 九七人妻一区二区三区| 久久国产青偷人人妻潘金莲| 五月天六月激情联盟网| 久久99一本色道亚洲精品| 日韩欧美91在线视频| 99热中文字幕在线精品| 中文字幕中文字幕在线十八区| 欧美精品在线观看国产|