Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android中wifi原理及流程分析

android中wifi原理及流程分析

編輯:關於Android編程

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.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.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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved