Android WLAN 开关和连接流程分析(二) 框架层

PS:上一节谈到frameworks层的WifiManager类是WLAN的核心类

所以我们这一节先从WifiManager展开。

一、WLAN开关分析

应用层中WifiSettings中new了WifiEnabler对象,在WifiEnabler中调用了WifiManager的setWifiEnabled()方法。

路径:frameworks/base/wifi/java/android/net/wifi/WfiManager.java

WfiManager->setWifiEnabled()

   /**
     * Enable or disable Wi-Fi.
     * <p>
     * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE}
     * permission to toggle wifi.
     *
     * @param enabled {@code true} to enable, {@code false} to disable.
     * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is
     *         either already in the requested state, or in progress toward the requested state.
     * @throws  {@link java.lang.SecurityException} if the caller is missing required permissions.
     */
    public boolean setWifiEnabled(boolean enabled) {
        try {
            return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

这里返回了一个服务调用结果

IWifiManager mService

路径:frameworks/base/wifi/java/android/net/wifi/IWifiManager.aidl    ps:注意是aidl

IWifiManager->setWifiEnabled()

那么我们需要找到IWifiManager.aidl相对应的Service  找到实现IWifiManager.Stub的类

 

WifiServiceImpl extends IWifiManager.Stub 

路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

WifiServiceImpl->setWifiEnabled()

   /**
     * see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)}
     * @param enable {@code true} to enable, {@code false} to disable.
     * @return {@code true} if the enable/disable operation was
     *         started or is already in the queue.
     */
    @Override
    public synchronized boolean setWifiEnabled(String packageName, boolean enable)
            throws RemoteException {
...
...
//判断是否飞行模式以及各种权限和打印日志,略过
...
        mWifiController.sendMessage(CMD_WIFI_TOGGLED);
        return true;
    }

这里发送了一条WLAN切换信息

WifiController  mWifiController

路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java

 

/**状态机
 * WifiController is the class used to manage on/off state of WifiStateMachine for various operating
 * modes (normal, airplane, wifi hotspot, etc.).
 */
public class WifiController extends StateMachine {

 

不同于WifiStateMachine ,WifiStateMachine是一个复杂的状态机,它维护了Wifi的启动、扫描、连接、断开等多个状态。WifiController 是高级别的wifi状态机,管理wifi开关,wifi热点开关等状态。

  WifiController(Context context, WifiStateMachine wsm, Looper wifiStateMachineLooper,
                   WifiSettingsStore wss, Looper wifiServiceLooper, FrameworkFacade f,
                   WifiStateMachinePrime wsmp) {
        super(TAG, wifiServiceLooper);
        mFacade = f;
        mContext = context;
        mWifiStateMachine = wsm;
        mWifiStateMachineLooper = wifiStateMachineLooper;
        mWifiStateMachinePrime = wsmp;
        mSettingsStore = wss;

        // CHECKSTYLE:OFF IndentationCheck
//添加各个状态及父状态
addState(mDefaultState); addState(mStaDisabledState, mDefaultState); addState(mStaEnabledState, mDefaultState); addState(mDeviceActiveState, mStaEnabledState); addState(mStaDisabledWithScanState, mDefaultState); addState(mEcmState, mDefaultState); // CHECKSTYLE:ON IndentationCheck boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn(); boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled(); boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable(); boolean isLocationModeActive = mSettingsStore.getLocationModeSetting(mContext) == Settings.Secure.LOCATION_MODE_OFF; log("isAirplaneModeOn = " + isAirplaneModeOn + ", isWifiEnabled = " + isWifiEnabled + ", isScanningAvailable = " + isScanningAlwaysAvailable + ", isLocationModeActive = " + isLocationModeActive); if (checkScanOnlyModeAvailable()) { setInitialState(mStaDisabledWithScanState); } else { setInitialState(mStaDisabledState); }

路径:frameworks/base/core/java/com/android/internal/util/StateMachine.java

addState()方法是父类StateMachine的方法,第一个参数是新添加的状态,第二个是其父状态。

       /**
         * Add a new state to the state machine. Bottom up addition
         * of states is allowed but the same state may only exist
         * in one hierarchy.
         *
         * @param state the state to add
         * @param parent the parent of state
         * @return stateInfo for this state
         */
        private final StateInfo addState(State state, State parent) {
            if (mDbg) {
                mSm.log("addStateInternal: E state=" + state.getName() + ",parent="
                        + ((parent == null) ? "" : parent.getName()));
            }
            StateInfo parentStateInfo = null;
            if (parent != null) {
                parentStateInfo = mStateInfo.get(parent);
                if (parentStateInfo == null) {
                    // Recursively add our parent as it‘s not been added yet.
                    parentStateInfo = addState(parent, null);
                }
            }
            StateInfo stateInfo = mStateInfo.get(state);
            if (stateInfo == null) {
                stateInfo = new StateInfo();
                mStateInfo.put(state, stateInfo);
            }

            // Validate that we aren‘t adding the same state in two different hierarchies.
            if ((stateInfo.parentStateInfo != null)
                    && (stateInfo.parentStateInfo != parentStateInfo)) {
                throw new RuntimeException("state already added");
            }
            stateInfo.state = state;
            stateInfo.parentStateInfo = parentStateInfo;
            stateInfo.active = false;
            if (mDbg) mSm.log("addStateInternal: X stateInfo: " + stateInfo);
            return stateInfo;
        }
StaDisabledState、StaEnabledState、StaDisabledWithScanState、EcmState的父状态都是DefaultState;而DeviceActiveState的父状态是StaEnabledState。
初始状态为StaDisableState
 class StaDisabledState extends State {
        private int mDeferredEnableSerialNumber = 0;
        private boolean mHaveDeferredEnable = false;
        private long mDisabledTimestamp;

        @Override
        public void enter() {
            mWifiStateMachinePrime.disableWifi();
            // Supplicant can‘t restart right away, so note the time we switched off
            mDisabledTimestamp = SystemClock.elapsedRealtime();
            mDeferredEnableSerialNumber++;
            mHaveDeferredEnable = false;
            mWifiStateMachine.clearANQPCache();
        }
...
...
在该状态下对接收到的CMD_WIFI_TOGGLED消息执行相应代码块。
 @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case CMD_WIFI_TOGGLED:
                    if (mSettingsStore.isWifiToggleEnabled()) {
                        if (doDeferEnable(msg)) {
                            if (mHaveDeferredEnable) {
                                //  have 2 toggles now, inc serial number and ignore both
                                mDeferredEnableSerialNumber++;
                            }
                            mHaveDeferredEnable = !mHaveDeferredEnable;
                            break;
                        }
                        transitionTo(mDeviceActiveState);
                    } else if (checkScanOnlyModeAvailable()) {
                        // only go to scan mode if we aren‘t in airplane mode
//进入扫描模式
if (mSettingsStore.isAirplaneModeOn()) { transitionTo(mStaDisabledWithScanState); } } break;
该状态下基本上没做处理然后切换到了DeviceActiveState。DeviceActiveState的父状态为StaEnabledState,
状态机的机制是,当转换为目标状态时,会依次调用父状态和本身的enter()方法。
StaEnableState
 class StaEnabledState extends State {
        @Override
        public void enter() {
            log("StaEnabledState.enter()");
        }
...
...//没做处理
DeviceActiveState
  class DeviceActiveState extends State {
        @Override
        public void enter() {
            mWifiStateMachinePrime.enterClientMode();
            mWifiStateMachine.setHighPerfModeEnabled(false);
        }
...
...
WifiStateMachinePrime mWifiStateMachinePrime
路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachinePrime.java
  /**
     * Method to switch wifi into client mode where connections to configured networks will be
     * attempted.
     */
    public void enterClientMode() {
        changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
    }
 private void changeMode(int newMode) {
        mModeStateMachine.sendMessage(newMode);
    }
ModeStateMachine mModeStateMachine
明显,ModeStateMachine也是状态机,是WifiStateMachinePrime的内部类
 private class ModeStateMachine extends StateMachine {
        // Commands for the state machine  - these will be removed,
        // along with the StateMachine itself
        public static final int CMD_START_CLIENT_MODE    = 0;
        public static final int CMD_START_SCAN_ONLY_MODE = 1;
        public static final int CMD_DISABLE_WIFI         = 3;

        private final State mWifiDisabledState = new WifiDisabledState();
        private final State mClientModeActiveState = new ClientModeActiveState();
        private final State mScanOnlyModeActiveState = new ScanOnlyModeActiveState();

        ModeStateMachine() {
            super(TAG, mLooper);

            addState(mClientModeActiveState);
            addState(mScanOnlyModeActiveState);
            addState(mWifiDisabledState);
...
...

ModeStateMachine有四种状态WifiDisabledState、ClientModeActiveState、ScanOnlyModeActiveState及父状态ModeActiveState。
初始也是关闭状态
WiFiDisableState
class WifiDisabledState extends ModeActiveState {
    @Override
    public void enter() {
        Log.d(TAG, "Entering WifiDisabledState");
        mDefaultModeManager.sendScanAvailableBroadcast(mContext, false);
        mScanRequestProxy.enableScanningForHiddenNetworks(false);
        mScanRequestProxy.clearScanResults();
    }
 
    @Override
    public boolean processMessage(Message message) {
    Log.d(TAG, "received a message in WifiDisabledState: " + message);
        if (checkForAndHandleModeChange(message)) {
            return HANDLED;
        }
    return NOT_HANDLED;
    }
 
    @Override
    public void exit() {
        // do not have an active mode manager...  nothing to clean up
    }
}
private boolean checkForAndHandleModeChange(Message message) {
    switch(message.what) {
        case ModeStateMachine.CMD_START_CLIENT_MODE:
            Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
            mModeStateMachine.transitionTo(mClientModeActiveState);
            break;
        case ModeStateMachine.CMD_START_SCAN_ONLY_MODE:
            Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode");
            mModeStateMachine.transitionTo(mScanOnlyModeActiveState);
            break;
        case ModeStateMachine.CMD_DISABLE_WIFI:
            Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled");
            mModeStateMachine.transitionTo(mWifiDisabledState);
            break;
        default:
            return NOT_HANDLED;
    }
    return HANDLED;
}

接着转换为ClientModeActiveState

       class ClientModeActiveState extends ModeActiveState {
            ClientListener mListener;
            private class ClientListener implements ClientModeManager.Listener {
...
            @Override
            public void enter() {
                Log.d(TAG, "Entering ClientModeActiveState");

                mListener = new ClientListener();
                mManager = mWifiInjector.makeClientModeManager(mListener);
                mManager.start();
                mActiveModeManagers.add(mManager);
                updateBatteryStatsWifiState(true);
            }
...

ActiveModeManager mManager 

ClientModeManager是ActiveModeManager的实现类

 

 /**
     * Start client mode.
     */
    public void start() {
        mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
    }

 

ClientModeStateMachine mStateMachine
ClientModeStateMachine也是一个状态机,有两种状态IdleState和StartedState
       ClientModeStateMachine(Looper looper) {
            super(TAG, looper);

            addState(mIdleState);
            addState(mStartedState);

            setInitialState(mIdleState);
            start();
        }

初始为IdleState状态

      private class IdleState extends State {

            @Override
            public void enter() {
                Log.d(TAG, "entering IdleState");
                mClientInterfaceName = null;
                mIfaceIsUp = false;
            }

            @Override
            public boolean processMessage(Message message) {
                switch (message.what) {
                    case CMD_START:
                        updateWifiState(WifiManager.WIFI_STATE_ENABLING,
                                        WifiManager.WIFI_STATE_DISABLED);

                        mClientInterfaceName = mWifiNative.setupInterfaceForClientMode(
                                false /* not low priority */, mWifiNativeInterfaceCallback);
                        if (TextUtils.isEmpty(mClientInterfaceName)) {
                            Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
                            updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
                                            WifiManager.WIFI_STATE_ENABLING);
                            updateWifiState(WifiManager.WIFI_STATE_DISABLED,
                                            WifiManager.WIFI_STATE_UNKNOWN);
                            break;
                        }
                        sendScanAvailableBroadcast(false);
                        mScanRequestProxy.enableScanningForHiddenNetworks(false);
                        mScanRequestProxy.clearScanResults();
                        transitionTo(mStartedState);
                        break;
                    default:
                        Log.d(TAG, "received an invalid message: " + message);
                        return NOT_HANDLED;
                }
                return HANDLED;
            }
        }

WifiNative mWifiNative 

路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java

/**
     * Setup an interface for Client mode operations.
     *
     * This method configures an interface in STA mode in all the native daemons
     * (wificond, wpa_supplicant & vendor HAL).
     *
     * @param lowPrioritySta The requested STA has a low request priority (lower probability of
     *                       getting created, higher probability of getting destroyed).
     * @param interfaceCallback Associated callback for notifying status changes for the iface.
     * @return Returns the name of the allocated interface, will be null on failure.
     */
    public String setupInterfaceForClientMode(boolean lowPrioritySta,
            @NonNull InterfaceCallback interfaceCallback) {
        synchronized (mLock) {
            if (!startHal()) {
                Log.e(TAG, "Failed to start Hal");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            if (!startSupplicant()) {
                Log.e(TAG, "Failed to start supplicant");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return null;
            }
            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
            if (iface == null) {
                Log.e(TAG, "Failed to allocate new STA iface");
                return null;
            }
            iface.externalListener = interfaceCallback;
            iface.name = createStaIface(iface, lowPrioritySta);
            if (TextUtils.isEmpty(iface.name)) {
                Log.e(TAG, "Failed to create STA iface in vendor HAL");
                mIfaceMgr.removeIface(iface.id);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
                return null;
            }
            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return null;
            }
            iface.networkObserver = new NetworkObserverInternal(iface.id);
            if (!registerNetworkObserver(iface.networkObserver)) {
                Log.e(TAG, "Failed to register network observer on " + iface);
                teardownInterface(iface.name);
                return null;
            }
            mWifiMonitor.startMonitoring(iface.name);
            // Just to avoid any race conditions with interface state change callbacks,
            // update the interface state before we exit.
            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
            initializeNwParamsForClientInterface(iface.name);
            Log.i(TAG, "Successfully setup " + iface);
            return iface.name;
        }
    }

startHal()

startSupplicant()

加载驱动setupInterfaceForClientMode()

另外启动了Wifi监视器startMonitoring()

startHal()

   /** Helper method invoked to start supplicant if there were no ifaces */
    private boolean startHal() {
        synchronized (mLock) {
            if (!mIfaceMgr.hasAnyIface()) {
                if (mWifiVendorHal.isVendorHalSupported()) {
                    if (!mWifiVendorHal.startVendorHal()) {
                        Log.e(TAG, "Failed to start vendor HAL");
                        return false;
                    }
                } else {
                    Log.i(TAG, "Vendor Hal not supported, ignoring start.");
                }
            }
            return true;
        }
    }
isVendorHalSupported()和startVendorHal()分别调用了HalDeviceManagerisSupported()和start()方法。

startSupplicant()实际上调用了WificondControlenableSupplicant()方法

   /**
    * Enable wpa_supplicant via wificond.
    * @return Returns true on success.
    */
    public boolean enableSupplicant() {
        if (!retrieveWificondAndRegisterForDeath()) {
            return false;
        }
        try {
            return mWificond.enableSupplicant();
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to enable supplicant due to remote exception");
        }
        return false;
    }
retrieveWificondAndRegisterForDeath()
  private boolean retrieveWificondAndRegisterForDeath() {
        if (mWificond != null) {
            if (mVerboseLoggingEnabled) {
                Log.d(TAG, "Wificond handle already retrieved");
            }
            // We already have a wificond handle.
            return true;
        }
        mWificond = mWifiInjector.makeWificond();
IWificond mWificond 
路径:system/connectivity/wificond/aidl/android/net/wifi/IWificond.aidl
其实现类为WiFiInjector
在上面的方法中被初始化
  public IWificond makeWificond() {
        // We depend on being able to refresh our binder in WifiStateMachine, so don‘t cache it.
        IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME);
        return IWificond.Stub.asInterface(binder);
    }

路径:frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiInjector.java
WIFICOND_SERVICE_NAME = wificond
ServiceManager.getService("wificond")直接调用了底层cpp
Status Server::enableSupplicant(bool* success) {
  *success = supplicant_manager_->StartSupplicant();
  return Status::ok();
}
路径:system/connectivity/wificond/server.cpp

 





 

 

 

 

 
 

 

 
 

 


 

Android WLAN 开关和连接流程分析(二) 框架层

上一篇:iPhone 手机发送短信,报告“尚未送达”


下一篇:[Algorithm] 448. Find All Numbers Disappeared in an Array