WIFI操作流程源码分析—启动

WIFI操作流程源码分析—启动

初始化

SystemServer 启动的时候,会生成WifiServiceConnectivityService 的实例,SystemServer.java

try {

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

}

ConnectivityService.java中构造函数ConnectivityService中创建DefaultNetworkFactory对象

public ConnectivityService(Context context, INetworkManagementService netManager,

            INetworkStatsService statsService, INetworkPolicyManager policyManager,

            NetworkFactory netFactory) {

           if (netFactory == null) {

            netFactory = new DefaultNetworkFactory(context, mTrackerHandler);

        }

}

DefaultNetworkFactory.java中创建类WifiStateTracker对象

private static class DefaultNetworkFactory implements NetworkFactory {

    @Override

        public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config) {

            switch (config.radio) {

                case TYPE_WIFI:

                    return new WifiStateTracker(targetNetworkType, config.name);

              }

        }

}

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

 

使能 WIFI

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

@Override

    public void onActivityCreated(Bundle savedInstanceState) {

 

    Switch actionBarSwitch = new Switch(activity);

 

    mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);

 

}

当用户按下 Wifi 切换按钮后,Android 会调用 WifiEnabler 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();

        }

    }

再由 WifiEnabler调用 WifiManager setWifiEnabled 接口函数,

public boolean setWifiEnabled(boolean enabled) {

        try {

            return mService.setWifiEnabled(enabled);

        } catch (RemoteException e) {

            return false;

        }

}

通过 AIDL,实际调用的是 WifiServicesetWifiEnabled 函数,

public synchronized boolean setWifiEnabled(boolean enable) {

        Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()

                + ", uid=" + Binder.getCallingUid());

        enforceChangePermission();

        mAirplaneModeOn.set(isAirplaneModeOn());

        if (mWifiStateMachine.hasCustomizedAutoConnect() && enable && mAirplaneModeOn.get()) {

            SXlog.i(TAG, "Can't enable wifi when airplane mode is on for customization.");

            return false;

        }

        if (DBG) {

            Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");

        }

 

        if (enable) {

            reportStartWorkSource();

        }

        mWifiStateMachine.setWifiEnabled(enable);

 

        /*

         * Caller might not have WRITE_SECURE_SETTINGS,

         * only CHANGE_WIFI_STATE is enforced

         */

 

        long ident = Binder.clearCallingIdentity();

        try {

            handleWifiToggled(enable);

        } finally {

            Binder.restoreCallingIdentity(ident);

        }

 

        if (enable) {

            if (!mIsReceiverRegistered) {

                registerForBroadcasts();

                mIsReceiverRegistered = true;

            }

        } else if (mIsReceiverRegistered) {

            mContext.unregisterReceiver(mReceiver);

            mIsReceiverRegistered = false;

        }

 

        return true;

    }

WifiService 接着通过WifiStateMachine中函数setWifiEnabled发送WIFI_STATE_ENABLING消息,

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

        }

    }

它做了两个动作,向状态机发送了2个消息

sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));加载驱动

sendMessage(CMD_START_SUPPLICANT);开启supplicant

加载驱动

状态机构造函数初始化时候,设置有个一个初始状态

        setInitialState(mInitialState);

我们进入mInitialState状态看看

        public void enter() {

            if (WifiNative.isDriverLoaded()) {

                transitionTo(mDriverLoadedState);

            }

            else {

                transitionTo(mDriverUnloadedState);

            }

因为最开始驱动都是没有加载的,所以进入transitionTo(mDriverUnloadedState);

transitionTo函数是状态切换的函数。

DriverUnloadedState类如下:

    class DriverUnloadedState extends State {

         @Override

        public boolean processMessage(Message message) {

               switch (message.what) {

                case CMD_LOAD_DRIVER:

                    mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING);

                   transitionTo(mWaitForP2pDisableState);

                    break;

                case WifiP2pService.P2P_ENABLE_PENDING:

                    mReplyChannel.replyToMessage(message, P2P_ENABLE_PROCEED);

                    break;

                default:

                    return NOT_HANDLED;

            }

            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);

            return HANDLED;

        }

    }

这里会处理刚才的CMD_LOAD_DRIVER这个消息,继续切换到mWaitForP2pDisableState

    class WaitForP2pDisableState extends State {

        @Override

        public boolean processMessage(Message message) {

            if (DBG) log(getName() + message.toString() + "\n");

            switch(message.what) {

                case WifiP2pService.WIFI_ENABLE_PROCEED:

                    //restore argument from original message (CMD_LOAD_DRIVER)

                    message.arg1 = mSavedArg;

                    transitionTo(mDriverLoadingState);

                    break;

    }

状态继续切换到mDriverLoadingState

这里回调用WifiNative.loadDriver()加载驱动,成功后发送消息CMD_LOAD_DRIVER_SUCCESS,否则CMD_LOAD_DRIVER_FAILURE

static JNINativeMethod gWifiMethods[] = {

    /* name, signature, funcPtr */

    { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },

};

由此可知会进入JNI

static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)

{

    return (jboolean)(::wifi_load_driver() == 0);

}

继续到wifi.c处理

int wifi_load_driver()

{

#ifdef WIFI_DRIVER_MODULE_PATH

    char driver_status[PROPERTY_VALUE_MAX];

    int count = 100; /* wait at most 20 seconds for completion */

    int status = -1;

 

    if (is_wifi_driver_loaded()) {

        return 0;

    }

    /* ensure that wlan driver config file exists (if specified) */

    if (ensure_wlan_driver_config_file_exists()) {

        return -1;

    }

    property_set(DRIVER_PROP_NAME, "loading");

 

    if(system(SDIO_POLLING_ON))

        LOGW("Couldn't turn on SDIO polling: %s", SDIO_POLLING_ON);

 

    if ('\0' != *DRIVER_SDIO_IF_MODULE_PATH) {

       if (insmod(DRIVER_SDIO_IF_MODULE_PATH, DRIVER_SDIO_IF_MODULE_ARG) < 0) {

           goto end;

       }

    }

 

    if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) {

        if ('\0' != *DRIVER_SDIO_IF_MODULE_NAME) {

           rmmod(DRIVER_SDIO_IF_MODULE_NAME);

        }

        goto end;

    }

 

    if (strcmp(FIRMWARE_LOADER,"") == 0) {

        /* usleep(WIFI_DRIVER_LOADER_DELAY); */

        property_set(DRIVER_PROP_NAME, "ok");

    }

    else {

        property_set("ctl.start", FIRMWARE_LOADER);

    }

 

    sched_yield();

    while (count-- > 0) {

        if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {

            if (strcmp(driver_status, "ok") == 0) {

                status = 0;

                goto end;

            }

            else if (strcmp(driver_status, "failed") == 0) {

                _wifi_unload_driver();

                goto end;

            }

        }

        usleep(200000);

    }

    property_set(DRIVER_PROP_NAME, "timeout");

    wifi_unload_driver();

end:

    system(SDIO_POLLING_OFF);

    return status;

#else

    property_set(DRIVER_PROP_NAME, "ok");

    return 0;

#endif

}

这里有几个比较重要的宏

#define WIFI_DRIVER_MODULE_PATH         "/system/lib/modules/wlan.ko"驱动模块地址

 

static const char SUPP_CONFIG_FILE[]    = "/data/misc/wifi/wpa_supplicant.conf";  supplicant配置文件

在这里wifi.c会跟wpa_supplicant通信,加载驱动

开启supplicant

另一个消息sendMessage(CMD_START_SUPPLICANT);DriverLoadedState处理

    class DriverLoadedState extends State {

        @Override

        public boolean processMessage(Message message) {

       

                case CMD_START_SUPPLICANT:

                    try {

                        mNwService.wifiFirmwareReload(mInterfaceName, "STA");

                    } catch (Exception e) {

                        loge("Failed to reload STA firmware " + e);

                        // continue

                    }

                   try {

                         mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);

                    } catch (RemoteException re) {

                        loge("Unable to change interface settings: " + re);

                    } catch (IllegalStateException ie) {

                        loge("Unable to change interface settings: " + ie);

                    }

 

                    if(WifiNative.startSupplicant()) {

                        if (DBG) log("Supplicant start successful");

                        mWifiMonitor.startMonitoring();

                        transitionTo(mSupplicantStartingState);

                    } else {

                        loge("Failed to start supplicant!");

                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));

                    }

                    break;

继续调用JNIWifiNative.startSupplicant(),过程差不多最后在wifi.c处理

int wifi_start_supplicant()

{

    return wifi_start_supplicant_common(SUPP_CONFIG_FILE);

}

int wifi_start_supplicant_common(const char *config_file)

最后也是在这里跟Wpa_supplicant驱动通信

WIFI状态切换

wifi状态发生改变的时候,wifistatemachine会通过setwifistate发送WIFI_STATE_CHANGED_ACTION消息通知外面

    private void setWifiState(int wifiState) {

        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);

        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);

        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);

        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);

        mContext.sendStickyBroadcast(intent);

}

例如在驱动加载状态

    class DriverLoadingState extends State {

            new Thread(new Runnable() {

                public void run() {

                    mWakeLock.acquire();

                    //enabling state

                    switch(message.arg1) {

                        case WIFI_STATE_ENABLING:

                            setWifiState(WIFI_STATE_ENABLING);

                            break;

                        case WIFI_AP_STATE_ENABLING:

                            setWifiApState(WIFI_AP_STATE_ENABLING);

                            break;

                    }

    }

wifisettings里面也有广播监听器

    public WifiSettings() {

        mFilter = new IntentFilter();

        mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);

 

        mReceiver = new BroadcastReceiver() {

            @Override

            public void onReceive(Context context, Intent intent) {

                handleEvent(context, intent);

            }

        };

        mScanner = new Scanner();

    }

 

当接受到广播会相应处理handleEvent

    private void handleEvent(Context context, Intent intent) {

        String action = intent.getAction();

        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {

            updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,

                   WifiManager.WIFI_STATE_UNKNOWN));

        }

    }

更新wifi状态

    private void updateWifiState(int state) {

        getActivity().invalidateOptionsMenu();

        switch (state) {

            case WifiManager.WIFI_STATE_ENABLED:

                mScanner.resume();

                return; // not break, to avoid the call to pause() below

            case WifiManager.WIFI_STATE_ENABLING:

                addMessagePreference(R.string.wifi_starting);

                break;

            case WifiManager.WIFI_STATE_DISABLED:

                addMessagePreference(R.string.wifi_empty_list_wifi_off);

                break;

        }

    }

比如 case WifiManager.WIFI_STATE_ENABLED:WIFI可用通知接受到的时候

  mScanner.resume();

Scanner resume函数

        void resume() {

            if (!hasMessages(0)) {

                sendEmptyMessage(0);

            }

        }

处理函数如下:

        @Override

        public void handleMessage(Message message) {

            if (mWifiManager.startScanActive()) {

                mRetry = 0;

            } else if (++mRetry >= 3) {

                mRetry = 0;

                Toast.makeText(getActivity(), R.string.wifi_fail_to_scan,

                        Toast.LENGTH_LONG).show();

                return;

            }

            sendEmptyMessageDelayed(0, WIFI_RESCAN_INTERVAL_MS);

        }

    }

会调用mWifiManager.startScanActive()进行ap的扫描。

所以当你点击wifi按钮,到驱动加载完成,发出WIFI_STATE_ENABLED消息的时候,wifi已经启动。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值