android Wifi frameworks

来源:互联网 发布:淘宝抽奖转盘真的假的 编辑:程序博客网 时间:2024/04/27 15:50

android wifi frameworks层的实现由不同的版本,本版本是android 4.2,有些内容与网上所传并不雷同,比如该版本实现中没有WifiLayer类。

Android_WIFI_Frameworks层的马拉松开始了。

 

Wifi 连接部分

一 Wifi初始化

 

     讲到Wifi的初始化,有必要了解Linux系统加载android的过程,该过程分为四个步骤

             init进程启动-Native服务启动-SystemServer(android服务启动)-Home设定

      主要关心第三步,因为这里涉及Wifi的初始化。

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

                     main()-- init1()--System_init()--init2()

     <frameworks/base/services/JNI/com_android_server_systemserver.cpp>

     <frameworks/base/cmds/system_server/Labrary/system_init.cpp>

     init2()主要代码如下:

        Thread thr = new ServerThread(); //调用构造函数
        thr.setName("android.server.ServerThread");
        thr.start(); //run()

     run()加载服务,servicemanager.addService(..),在run()函数中注意这段代码。

           try {
                Slog.i(TAG, "Wi-Fi Service");
                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);
            }

      第一段代码创建WifiService对象,第二段代码调用了checkAndStartWifi()方法。下面我们只需要关注WifiService类的实现了。

     WifiService构造函数: mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);

     checkAndStartWifi(): if (wifiEnabled) setWifiEnabled(wifiEnabled);----------------------------

     //很明显,wifiEnabled为false,不能调用setWifiEnabled()函数。

    到此,Wifi的初始化告一段落。

 

二  Wifi启动,Scan AP, 配置AP和获取IP    

      WifiSettings>/frameworks/base/setttings/src/com/android/setttings/wifi

      在Activity显示之前调用onActivityCreated()函数

       if (!mSetupWizardMode) {   

              mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);

         } 

        转到WifiEnabler类

        ——————————————————————————————————————

        CheckBox和RadioBox都是从CompoundButton中继承的,而CompoundButton是继承TextView。

  <CheckBox
      android:id="@+id/mycheckbox"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="This checkbox is:uncheck"
      />

    常用的checkcbox函数有:isChecked(),setChecked(),toggle()(改变状态,如是checked的变成unchecked,如果是unchecked变为checked。)。如果CheckBox的状态发

     生更改,需要在程序中进行触发方法处理。如下:

public class HelloAndriod extends Activity implements CompoundButton.OnCheckedChangeListener{

    private CheckBox mycheckbox = null;
   
    @Override
    public void onCreate(Bundle savedInstanceState){
        ... ...
        mycheckbox = (CheckBox)findViewById(R.id.mycheckbox);
        mycheckbox.setOnCheckedChangeListener(this);

    }
   
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
           mycheckbox.setText("This checkbox is : " + (isChecked ? "checked":"unchcked"));
    }
}

----------------------------------------------------------------------------------------------------------------------------------

    所以当CompoundButton状态发生改变时,调用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();
        }

    }

    继而  mWifiManager.setWifiEnabled()-----mService.setWifiEnabled(enabled)---------mWifiStateMachine.setWifiEnabled(enable);

   最终到WifiStateMachine类

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

   而在WifiService构造函数中创建了WifiStateMachine对象,在WifiStateMachine构造函数中设置状态机初始状态为

  mInitialState,如果你懂得了状态机的实现机制,

  sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0))>>>>>进入mInitialState查看

   mInitialState

    public void enter() {

       if (mWifiNative.isDriverLoaded()) {
                transitionTo(mDriverLoadedState);
            }
            else {
                transitionTo(mDriverUnloadedState);
            } }

   因为没有加载驱动,所以跳到mDriverUnloadedState状态,transitionTo()函数实现简单。

         mDriverUnloadedState

          public boolean processMessage(Message message) {
            if (DBG) log(getName() + message.toString() + "\n");
            switch (message.what) {
                case CMD_LOAD_DRIVER:
                    transitionTo(mDriverLoadingState);
                    break;
                default:
                    return NOT_HANDLED;
                }
                    return HANDLED;
             }

          mDriverLoadingState

          public boolean processMessage(Message message) {
            if (DBG) log(getName() + message.toString() + "\n");
            switch (message.what) {
                case CMD_LOAD_DRIVER:
                    transitionTo(mDriverLoadingState);
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
            }

          mDriverLoadingState(enter())<在这里插一条,必须时刻关注WIFI_State_,其定义在WifiManager.java中 >


           if(mWifiNative.loadDriver()) {
                     sendMessage(CMD_LOAD_DRIVER_SUCCESS);
                      } else {}

            讲到这里,需要谈谈WifiNative.java了,顾名思义,本地接口

         运行到文件android_net_wifi_Wifi.cpp<frameworks/base/core/Java/android/JNI>

           static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
            {
                  return (jboolean)(::wifi_unload_driver() == 0);
             }

          继续调用至文件wifi.c<hardware/hardware_legency/wifi.c>

         int wifi_load_driver(){}

 

           回到Frameworks层代码,如果驱动加载成功,sendMessage(CMD_LOAD_DRIVER_SUCCESS);

           因为当前状态为mDriverLoadingState,回到该状态下的ProcessMessage()

        switch (message.what) {
                case CMD_LOAD_DRIVER_SUCCESS:
                      transitionTo(mDriverLoadedState);

           mDriverLoadedState

 

      到达该状态后驱动加载成功,回到先前的代码,开始执行语句sendMessage(CMD_START_SUPPLICANT);


        因为当前状态为mDriverLoadedState,所以运行该状态下的processMessage>>

          public boolean processMessage(Message message) {

               case CMD_START_SUPPLICANT:

                              if(mWifiNative.startSupplicant(mP2pSupported)) {
                                             mWifiMonitor.startMonitoring();
                                             transitionTo(mSupplicantStartingState);
                                }

             }

            状态切换到mSupplicantStartingState,并启动mWifiMonitor监控线程,跳到startMonitoring()>>

        -----------------------------------------------------------

                 public void startMonitoring() {
                      new MonitorThread().start();
             }

           运行到run()函数>>>>

                if (connectToSupplicant()) {
                         mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
                  } else {
                         mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
                  }

           因为状态机当前状态为mSupplicantStartingState,调用该状态下的processMessage>>>

            switch(message.what) {
                case WifiMonitor.SUP_CONNECTION_EVENT:
                                 setWifiState(WIFI_STATE_ENABLED);
                                 mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
                                 mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
     
                            mWifiInfo.setMacAddress(mWifiNative.getMacAddress());
                                 mWifiConfigStore.initialize();
                                 initializeWpsDetails();

                                sendSupplicantConnectionChangedBroadcast(true);
                                transitionTo(mDriverStartedState);

                      }

           >>运行到这里,不要想当然:mSupplicantStartingState一定要切换到mSupplicantStartedState。

        setWifiState(WIFI_STATE_ENABLED)跳到WifiSettings.java

        mScanner.resume()// mScanner继承Handler

        -----------------------------------------------------

        mDriverStartedState

        当有外部事件传来时,调用handlemessage()

                public void handleMessage(Message message) {
                             if (mWifiManager.startScanActive()) {
                                    mRetry = 0;
                              } else if (++mRetry >= 3) {
                                    mRetry = 0;
                            Activity activity = getActivity();
                            if (activity != null) {
                                  Toast.makeText(activity, R.string.wifi_fail_to_scan,
                                   Toast.LENGTH_LONG).show();
                            }  }

             >>mWifiManager.startScanActive()>>mService.startScan(true)

               public void startScan(boolean forceActive) {
                         enforceChangePermission();
                         mWifiStateMachine.startScan(forceActive);
                        noteScanStart();
                  }

             主要跟踪这两个函数

          1、mWifiStateMachine.startScan(forceActive)

                 public void startScan(boolean forceActive) {
                               sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
                               SCAN_ACTIVE : SCAN_PASSIVE, 0));
                    }

                   跳到mDriverStartedState下的processMessage()

                              switch(message.what) {
                                case CMD_START_SCAN:
                                         boolean forceActive = (message.arg1 == SCAN_ACTIVE);
                                        if (forceActive && !mSetScanActive) {
                                               mWifiNative.setScanMode(forceActive);
                                          }
                                        mWifiNative.scan();
                                       if (forceActive && !mSetScanActive) {
                                             mWifiNative.setScanMode(mSetScanActive);
                                           }

                                  }

                      ------------------------------------------------------------------------------------

                                    public boolean setScanMode(boolean setActive) {
                                           if (setActive) {
                                                return doBooleanCommand("DRIVER SCAN-ACTIVE");
                                           } else {
                                               return doBooleanCommand("DRIVER SCAN-PASSIVE");
                                            }   }

                                  public boolean scan() {
                                           return doBooleanCommand("SCAN");
                                   }          

                       --------------------------------------------------------------------------------------         

           2、noteScanStart()

                  private void noteScanStart() {
                              WorkSource scanWorkSource = null;
                              synchronized (WifiService.this) {
                              if (mScanWorkSource != null) {
                                     return;
                                  }
                              scanWorkSource = new WorkSource(Binder.getCallingUid());
                              mScanWorkSource = scanWorkSource;
                                 }

                               }

            运行到这里,等待wpa_supplicant返回Scan结果

                    else if (eventName.equals(SCAN_RESULTS_STR))
                       event = SCAN_RESULTS;

              >>>>>       

                    void handleEvent(int event, String remainder) {
                            switch (event) {
                                 case SCAN_RESULTS:
                                      mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
                                      break;   }
                       }

              ---------------------------------------------------

               运行到这里,因为当前状态为mDriverStartedState,你是否会去找该状态下的processMessage()

           没错,你方向是对的,但是为什么processMessage()中没有处理SCAN_RESULTS_EVENT事件

           的case语句,因为处理该事件的case语句包含在mSupplicantStartedState的processMessage()函数

           中,参考状态机的实现机制。

           ---------------------------------

               case WifiMonitor.SCAN_RESULTS_EVENT:
                    setScanResults(mWifiNative.scanResults());
                       if (!mhasCMCCSavedToConfig) {
                                WifiConfiguration wc = fetchConfigFromScanResults("CMCC");
                                sendScanResultsAvailableBroadcast();
                               mScanResultIsPending = false;

                            }break;

                       }

                这段代码中涉及CMCC,留待下面的环节细看

            >>>>sendScanResultsAvailableBroadcast()

           >>>

               private void sendScanResultsAvailableBroadcast() {
                         Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                         mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
                 }

               >>>wifiSettings.java

           updateAccessPoints();  
                   switch (wifiState) {
                          case WifiManager.WIFI_STATE_ENABLED:
                                     final Collection<AccessPoint> accessPoints = constructAccessPoints();
                                     Log.d(TAG, "remove all preference");
                                     getPreferenceScreen().removeAll();
                                     if(accessPoints.size() == 0) {
                                       addMessagePreference(R.string.wifi_empty_list_wifi_on);
                                       }
                                           for (AccessPoint accessPoint : accessPoints) {
                                           Log.d(TAG, "add preference accessPoint = " + accessPoint);
                                            getPreferenceScreen().addPreference(accessPoint);
                                      }
                             break;

                    }

        配置ap参数>>>当用户点击某一个ap时出现ap配置对话框

           private void showDialog(AccessPoint accessPoint, boolean edit) {
                       Log.d(TAG, "Enter showDialog edit = " + edit + " accessPoint = " + accessPoint);
                      if (mDialog != null) {
                             Log.d(TAG, "remove WIFI_DIALOG");
                             removeDialog(WIFI_DIALOG_ID);
                      mDialog = null;
                       }

                mDlgAccessPoint = accessPoint;
               mDlgEdit = edit;

                   showDialog(WIFI_DIALOG_ID);
               }

            连接ap>>>>>>>>connectDuetoAutoConnectMode()

           private void connectDuetoAutoConnectMode(WifiConfiguration config, WifiManager.ActionListener listener) {
                 if (!mAutoConnect) {
                       mWifiManager.enableNetwork(INVALID_NETWORK_ID, true);
                 }
                       mWifiManager.connect(config, listener);
                }

          mWifiManager.enableNetwork()>>>>mWifiService.enableNetwork()

       >>>mWifiStateMachine.syncenableNetwork()

           public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
                    Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
                            disableOthers ? 1 : 0);
               }

         >>mSupplicantStartedState的processMessage()

      >>  case CMD_ENABLE_NETWORK:
                    ok = mWifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
                    break;

       >>  mWifiConfigStore.enableNetwork()

                    boolean enableNetwork(int netId, boolean disableOthers) {
                             boolean ret = enableNetworkWithoutBroadcast(netId, disableOthers);
                            if (disableOthers) {
                               sendConfiguredNetworksChangedBroadcast();
                            } else {
                             WifiConfiguration enabledNetwork = null;
                             synchronized(mConfiguredNetworks) {
                             enabledNetwork = mConfiguredNetworks.get(netId);
            }
                    if (enabledNetwork != null) {
                           sendConfiguredNetworksChangedBroadcast(enabledNetwork,
                             WifiManager.CHANGE_REASON_CONFIG_CHANGE);
                      }
             }
        
 >>> enableNetworkWithoutBroadcast()

      >>

                  boolean enableNetworkWithoutBroadcast(int netId, boolean disableOthers) {
                               boolean ret = mWifiNative.enableNetwork(netId, disableOthers);
                   

                               WifiConfiguration config = mConfiguredNetworks.get(netId);

                    }

       >>>mWifiNative.enableNetwork()

---------------------------------------------------------------------------------------

    接下来很重要的一步就是启动DHCP分配IP地址

    ObtainingIpState

   >>enter()

   >>>     

      mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);

    >>>跳到frameworks/base/core/java/net/DHCP/DhcpStateMachine.java

     >>>  该状态机初始状态为StoppedState

           switch (message.what) {
                case CMD_START_DHCP:
                    if (mRegisteredForPreDhcpNotification) {
                               mController.sendMessage(CMD_PRE_DHCP_ACTION);
                                transitionTo(mWaitBeforeStartState);
                    }

       >>>>>跳到WifiStateMachine.java

      >>因为mL2ConnectedState是mObtainingIpState的父亲,调用

           mL2ConnectedState中的processMessage()

      >>>

               switch (message.what) {
                    case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
                          handlePreDhcpSetup();
                          mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
                          break;

                  }

        >>>跳到frameworks/base/core/java/net/DHCP/DhcpStateMachine.java

      该状态机当前状态为WaitBeforeStartState,执行该状态下的processMessage()

      >>> 

          switch (message.what) {
                 case CMD_PRE_DHCP_ACTION_COMPLETE:
                    if (runDhcp(DhcpAction.START)) {
                        transitionTo(mRunningState);}

      >>>runDhcp()>>NetworkUtils.runDhcp()

       private boolean runDhcp(DhcpAction dhcpAction) {
        boolean success = false;
        DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();

        if (dhcpAction == DhcpAction.START) {
            if (DBG) Log.d(TAG, "DHCP request on " + mInterfaceName);
            success = NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal);
            mDhcpInfo = dhcpInfoInternal;
        }

    //framework/base/core/jni/android_net_NetUtils.cpp

   接下来就是调用底层代码了,启动DHCP后就可以分配IP地址了


还有些东西没有贴出,如需进一步了解,请加QQ:398024684

 

        


                       


   

      

原创粉丝点击