android中wifi原理及流程分析(很经典)

wifi相关的文件位置:

WIFISettings应用程序位于

      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 的实例,

classServerThreadextends 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中的  

 publicstatic ConnectivityServicegetInstance(Context context) {

       return ConnectivityThread.getServiceInstance(context);

   }函数,继续往下看:

       publicstatic ConnectivityService getServiceInstance(Context context) {

           ConnectivityThreadthread = 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;

       }

   }

继续往下跟:

privatestatic class ConnectivityThread extends Thread {

       privateContext mContext;

 

       privateConnectivityThread(Context context) {

           super("ConnectivityThread");

           mContext= context;

       }

       @Override

        publicvoid run() {

           Looper.prepare();

           synchronized(this) {

               sServiceInstance= newConnectivityService(mContext);

               notifyAll();

           }

           Looper.loop();

       }

       publicstatic ConnectivityService getServiceInstance(Context context) {

           ConnectivityThreadthread = 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");

                   }

               }

           }

           returnsServiceInstance;

       }

   }

继续newConnectivityService(mContext)

privateConnectivityService(Context context) {

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

   for(int netType : mPriorityList) {

           switch(mNetAttributes[netType].mRadio) {

           caseConnectivityManager.TYPE_WIFI:

               Slog.v(TAG,"Starting Wifi Service.");

               WifiStateTracker wst =newWifiStateTracker(context, mHandler);

               WifiServicewifiService = 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

publicclassWifiEnabler 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 中的监视线程。

WifiServiceWifiService.java收到MESSAGE_ENABLE_WIFI 消息后的操作如下:

AIDL:

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

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

接下来继续道wifiService.Java

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

   public boolean setWifiEnabled(booleanenable) {

       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());  //  heresend a mesage to himself

       }

       return true;

   }

继续往下:

   private void sendEnableMessage(booleanenable,boolean persist, int uid) {

       Message msg= Message.obtain(mWifiHandler,

                                    (enable ?MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),

                                    (persist ? 1 : 0), uid);

       msg.sendToTarget();

   }

WifiHandler会收到消息:

privateclass WifiHandlerextendsHandler {

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

publicvoidhandleMessage(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_ACTIONWifiLayer中注册了ActionReceiver
WifiLayer收到此Action后开始scan的流程,具体如下

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

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

Wifi连接

具体流程参见以下流程图

 

 

IP地址的配置
流程如图

到此结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值