Android R wifi 状态机消息处理机制以及状态切换流程分析

0. 从wifi使能开始

07-27 11:41:41.743 I/WifiService( 1675): setWifiEnabled package=com.android.systemui uid=10131 enable=true

07-27 11:41:41.751 D/WifiActiveModeWarden( 1675): Starting ClientModeManager

07-27 11:41:41.755 D/QCNEJ/WlanStaInfoRelay( 2695): onChange for uri = content://settings/global/wifi_on
07-27 11:41:41.763 D/WifiController( 1675): DisabledState.exit()
07-27 11:41:41.763 D/WifiController( 1675): EnabledState.enter()
07-27 11:41:41.764 D/WifiClientModeManager( 1675): entering IdleState

07-27 11:41:42.319 D/WifiMonitor( 1675): startMonitoring(wlan0)

07-27 11:41:42.320 I/WifiNative( 1675): Interface state changed on Iface:{Name=wlan0,Id=9,Type=STA_SCAN}, isUp=true
07-27 11:41:42.320 I/WifiNative( 1675): Successfully setup Iface:{Name=wlan0,Id=9,Type=STA_SCAN}
07-27 11:41:42.322 E/SupplicantStaIfaceHal( 1675): Can't call getKeyMgmtCapabilities_1_3, ISupplicantStaIface is null
07-27 11:41:42.322 V/SupplicantStaIfaceHal( 1675): getAdvancedKeyMgmtCapabilities: Capability flags = 0
07-27 11:41:42.323 V/WifiHAL (  850): WifiVendorCommand 0x7ff681c200 created vendor_id:0x1374 subcmd:38

07-27 11:41:42.327 D/WifiClientModeManager( 1675): entering StartedState

07-27 11:41:42.329 D/WifiClientModeManager( 1675): entering ScanOnlyModeState
07-27 11:41:42.329 D/WifiClientModeImpl( 1675): setting operational mode to 2 for iface: wlan0
07-27 11:41:42.330 D/WifiScanRequestProxy( 1675): Sending scan available broadcast: true
07-27 11:41:42.330 D/WifiHandler.WifiScanningService( 1675): handleMessage Received message=159774 sendingUid=1000
07-27 11:41:42.330 I/WifiScanningService( 1675): Received a request to enable scanning, UID = 1000
07-27 11:41:42.330 I/WifiScanRequestProxy( 1675): Scanning is enabled
07-27 11:41:42.330 I/WifiScanRequestProxy( 1675): Scanning for hidden networks is disabled
07-27 11:41:42.331 I/WifiService( 1675): getSupportedFeatures uid=1000
07-27 11:41:42.331 D/WakeupController( 1675): start()
07-27 11:41:42.331 E/WifiHAL (  850): wifi_get_gscan_capabilities: GSCAN is not supported by driver
07-27 11:41:42.332 E/WifiVendorHal( 1675): getBgScanCapabilities(l.674) failed {.code = ERROR_NOT_SUPPORTED, .description = }

07-27 11:41:42.332 D/WifiAsyncChannel.WifiService( 1675): sendMessageSynchronously sendMessageSynchronously.send message=131133
07-27 11:41:42.332 D/WakeupController( 1675): Setting active to true

07-27 11:41:42.338 I/WifiScanningService( 1675): Created a new impl for wlan0
07-27 11:41:42.339 D/WifiHandler.WifiScanningService( 1675): handleMessage Received message=159771 sendingUid=1000
07-27 11:41:42.339 D/WifiScanningService( 1675): replySucceeded replySucceeded recvdMessage=159771
07-27 11:41:42.340 D/WifiHandler.WifiScanningService( 1675): handleMessage Received message=159773 sendingUid=1000
07-27 11:41:42.340 I/WifiScanningService( 1675): wifi driver loaded with scan capabilities: max buckets=16

07-27 11:41:42.340 D/WifiScanningService( 1675): replySucceeded replySucceeded recvdMessage=159773

07-27 11:41:42.343 D/WakeupController( 1675): Saved networks in most recent scan:[]
07-27 11:41:42.343 D/WakeupLock( 1675): Lock set. Number of networks: 0

07-27 11:41:42.345 D/WifiClientModeImpl( 1675):  DefaultState screen=on 0 0
07-27 11:41:42.345 D/WifiClientModeImpl( 1675): setting wifi state to: 2

07-27 11:41:42.346 D/WifiP2pService( 1675): Wifi enabled=false, P2P Interface availability=true
07-27 11:41:42.347 D/WifiP2pService( 1675): P2pDisabledState{ when=0 what=143377 target=com.android.wifi.x.com.android.internal.util.StateMachine$SmHandler }
07-27 11:41:42.347 D/WifiP2pService( 1675): DefaultState{ when=0 what=143377 target=com.android.wifi.x.com.android.internal.util.StateMachine$SmHandler }
07-27 11:41:42.347 I/QCC:EventsManager( 3505): Received WIFI_STATE_CHANGE_ACTION

07-27 11:41:42.348 I/QCC:EventsManager( 3505): Received WIFI_STATE_CHANGED_ACTION : WIFI_STATE_ON
07-27 11:41:42.348 I/QCC:ActiveCareService( 3505): Wifi event manager post event:IPTH_EVENT_CANCEL

07-27 11:41:42.348 I/SupplicantStaIfaceHal( 1675): Starting supplicant using HIDL
07-27 11:41:42.348 I/QCC:NetworkStat( 3505): getActiveNetwork(ctx) invoked.

07-27 11:41:42.349 D/BluetoothAdapterService(19354): android.net.wifi.WIFI_STATE_CHANGED
07-27 11:41:42.349 I/hwservicemanager(  585): Since android.hardware.wifi.supplicant@1.0::ISupplicant/default is not registered, trying to start it as a lazy HAL.
07-27 11:41:42.350 I/WifiService( 1675): getWifiEnabledState uid=10131
07-27 11:41:42.350 D/SupplicantStaIfaceHal( 1675): Successfully triggered start of supplicant using HIDL
07-27 11:41:42.350 I/QCC:NetworkStat( 3505): no available network
07-27 11:41:42.351 D/BluetoothAdapterService(19354): java.lang.SecurityException: WifiService: Neither user 1002 nor current process has android.permission.NETWORK_SETTINGS.
07-27 11:41:42.351 D/BluetoothVendorService(19354): getPowerBackoff 

07-27 11:41:42.390 D/wpa_supplicant( 7847): wpa_supplicant v2.10-devel-11
07-27 11:41:42.390 D/wpa_supplicant( 7847): Global control interface '@android:vendor_wpa_wlan0'
07-27 11:41:42.390 D/wpa_supplicant( 7847): Using Android control socket 'vendor_wpa_wlan0'
07-27 11:41:42.390 D/wpa_supplicant( 7847): Initing hidl control
07-27 11:41:42.390 I/wpa_supplicant( 7847): Processing hidl events on FD 5
07-27 11:41:42.390 D/wpa_supplicant( 7847): hidl_register service name default

当wifi打开时,会出现以上的log,我们从setWifiEnabled开始整理。

/framework/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

    /**
     * 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) {
        if (enforceChangePermission(packageName) != MODE_ALLOWED) {
            return false;
        }
        boolean isPrivileged = isPrivileged(Binder.getCallingPid(), Binder.getCallingUid());
        if (!isPrivileged && !isDeviceOrProfileOwner(Binder.getCallingUid(), packageName)
                && !mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q,
                  Binder.getCallingUid())
                && !isSystem(packageName, Binder.getCallingUid())) {
            mLog.info("setWifiEnabled not allowed for uid=%")
                    .c(Binder.getCallingUid()).flush();
            return false;
        }
        // If Airplane mode is enabled, only privileged apps are allowed to toggle Wifi
        if (mSettingsStore.isAirplaneModeOn() && !isPrivileged) {
            mLog.err("setWifiEnabled in Airplane mode: only Settings can toggle wifi").flush();
            return false;
        }

        // If SoftAp is enabled, only privileged apps are allowed to toggle wifi
        if (!isPrivileged && mTetheredSoftApTracker.getState() == WIFI_AP_STATE_ENABLED) {
            mLog.err("setWifiEnabled with SoftAp enabled: only Settings can toggle wifi").flush();
            return false;
        }
        //这句正好对应log中的第一句,会打印打开wifi的package信息。
        mLog.info("setWifiEnabled package=% uid=% enable=%").c(packageName)
                .c(Binder.getCallingUid()).c(enable).flush();
        long ident = Binder.clearCallingIdentity();
        try {
            if (!mSettingsStore.handleWifiToggled(enable)) {
                // Nothing to do if wifi cannot be toggled
                return true;
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        if (mWifiPermissionsUtil.checkNetworkSettingsPermission(Binder.getCallingUid())) {
            mWifiMetrics.logUserActionEvent(enable ? UserActionEvent.EVENT_TOGGLE_WIFI_ON
                    : UserActionEvent.EVENT_TOGGLE_WIFI_OFF);
        }

        if (!mIsControllerStarted) {
            Log.e(TAG,"WifiController is not yet started, abort setWifiEnabled");
            return false;
        }

        mWifiMetrics.incrementNumWifiToggles(isPrivileged, enable);
        //最后调用这个函数继续处理enabled操作
        mActiveModeWarden.wifiToggled();
        return true;
    }

mActiveModeWarden.wifiToggled()的实质就是发送CMD_WIFI_TOGGLED消息给WifiController。

    /** Wifi has been toggled. */
    public void wifiToggled() {
        mWifiController.sendMessage(WifiController.CMD_WIFI_TOGGLED);
    }

1. WifiController

WifiController其实就是一个状态机,它是用来管理normal,airplane,hostpot等wifi状态切换。在R版本中这个状态机是定义在ActiveModeWarden.java中(Q版本则是在WifiController.java),R版本中定义的wifi状态只有DisabledStateEnableState,相比Q版本精简了很多状态。

        WifiController() {
            super(TAG, mLooper);

            DefaultState defaultState = new DefaultState();
            addState(defaultState); {
                addState(mDisabledState, defaultState);
                addState(mEnabledState, defaultState);
            }

            setLogRecSize(100);
            setLogOnlyTransitions(false);

        }

状态机处理机制:

  1. 当前状态处理消息,能处理就处理,不能处理抛给父类状态,直至处理完或无状态处理
  2. 若当前状态处理消息过程中涉及状态变化,则依次进入退出状态的exit方法和进入状态的enter方法

所以wifi在使能时,肯定是从DisableSate.exit -> EnableState.enter状态切换,下面结合代码:

        class DisabledState extends BaseState {
            @Override
            public void enter() {
                log("DisabledState.enter()");
                mWifiControllerReady = true;
                super.enter();
                if (hasAnyModeManager()) {
                    Log.e(TAG, "Entered DisabledState, but has active mode managers");
                }
            }

            @Override
            public void exit() {
                log("DisabledState.exit()");
                super.exit();
            }

            @Override
            public boolean processMessageFiltered(Message msg) {
                switch (msg.what) {
                    case CMD_WIFI_TOGGLED:
                    case CMD_SCAN_ALWAYS_MODE_CHANGED:
                        if (shouldEnableSta()) {
                            startClientModeManager();
                            //切换wifi状态。
                            transitionTo(mEnabledState);
                        }
                        break;
                //...
                }
                return HANDLED;
            }
        }
    /**
     * Method to enable a new client mode manager.
     */
    private boolean startClientModeManager() {
        Log.d(TAG, "Starting ClientModeManager");
        ClientListener listener = new ClientListener();
        ClientModeManager manager = mWifiInjector.makeClientModeManager(listener);
        listener.setActiveModeManager(manager);
        //执行ClientModeManager.start方法
        manager.start();
        //下面这个函数会在下面讲述,最终会启动wpa_supplicant
        if (!switchClientModeManagerRole(manager)) {
            return false;
        }
        mActiveModeManagers.add(manager);
        return true;
    }

ClientModeManager(Context context, @NonNull Looper looper, Clock clock, WifiNative wifiNative,
            Listener listener, WifiMetrics wifiMetrics, SarManager sarManager,
            WakeupController wakeupController, ClientModeImpl clientModeImpl) {
        mContext = context;
        mClock = clock;
        mWifiNative = wifiNative;
        mModeListener = listener;
        mWifiMetrics = wifiMetrics;
        mSarManager = sarManager;
        mWakeupController = wakeupController;
        mClientModeImpl = clientModeImpl;
        mStateMachine = new ClientModeStateMachine(looper);
        mDeferStopHandler = new DeferStopHandler(TAG, looper);
    }

    /**
     * Start client mode.
     */
    @Override
    public void start() {
        mTargetRole = ROLE_CLIENT_SCAN_ONLY;
        //这边也就是发送CMD_START给ClientModeStateMachine这个状态机
        mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
    }

2.ClientModeStateMachine

    private class ClientModeStateMachine extends StateMachine {
        // Commands for the state machine.
        public static final int CMD_START = 0;
        public static final int CMD_SWITCH_TO_SCAN_ONLY_MODE = 1;
        public static final int CMD_SWITCH_TO_CONNECT_MODE = 2;
        public static final int CMD_INTERFACE_STATUS_CHANGED = 3;
        public static final int CMD_INTERFACE_DESTROYED = 4;
        public static final int CMD_INTERFACE_DOWN = 5;
        public static final int CMD_SWITCH_TO_SCAN_ONLY_MODE_CONTINUE = 6;
        private final State mIdleState = new IdleState();
        private final State mStartedState = new StartedState();
        private final State mScanOnlyModeState = new ScanOnlyModeState();
        private final State mConnectModeState = new ConnectModeState();

        private final InterfaceCallback mWifiNativeInterfaceCallback = new InterfaceCallback() {
            @Override
            public void onDestroyed(String ifaceName) {
                if (mClientInterfaceName != null && mClientInterfaceName.equals(ifaceName)) {
                    Log.d(TAG, "STA iface " + ifaceName + " was destroyed, stopping client mode");

                    // we must immediately clean up state in ClientModeImpl to unregister
                    // all client mode related objects
                    // Note: onDestroyed is only called from the main Wifi thread
                    mClientModeImpl.handleIfaceDestroyed();

                    sendMessage(CMD_INTERFACE_DESTROYED);
                }
            }

            @Override
            public void onUp(String ifaceName) {
                if (mClientInterfaceName != null && mClientInterfaceName.equals(ifaceName)) {
                    sendMessage(CMD_INTERFACE_STATUS_CHANGED, 1);
                }
            }

            @Override
            public void onDown(String ifaceName) {
                if (mClientInterfaceName != null && mClientInterfaceName.equals(ifaceName)) {
                    sendMessage(CMD_INTERFACE_STATUS_CHANGED, 0);
                }
            }
        };

        ClientModeStateMachine(Looper looper) {
            super(TAG, looper);

            // CHECKSTYLE:OFF IndentationCheck
            //定义的集中状态机状态
            addState(mIdleState);
            addState(mStartedState);
                addState(mScanOnlyModeState, mStartedState);
                addState(mConnectModeState, mStartedState);
            // CHECKSTYLE:ON IndentationCheck

            //初始化原始状态为IdleState
            setInitialState(mIdleState);
            start();
        }

        private class IdleState extends State {
            @Override
            public void enter() {
                //对应log打印出来
                Log.d(TAG, "entering IdleState");
                mClientInterfaceName = null;
                mIfaceIsUp = false;
            }

            @Override
            public boolean processMessage(Message message) {
                switch (message.what) {
                    case CMD_START:
                        // Always start in scan mode first.
                        //接收到发送过来的CMD_START,执行这句
                        mClientInterfaceName =
                                mWifiNative.setupInterfaceForClientInScanMode(
                                mWifiNativeInterfaceCallback);
                        if (TextUtils.isEmpty(mClientInterfaceName)) {
                            Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
                            mModeListener.onStartFailure();
                            break;
                        }
                        transitionTo(mScanOnlyModeState);
                        break;
                    default:
                        Log.d(TAG, "received an invalid message: " + message);
                        return NOT_HANDLED;
                }
                return HANDLED;
            }
        }
    /**
     * Setup an interface for client mode (for scan) operations.
     *
     * This method configures an interface in STA mode in the native daemons
     * (wificond, vendor HAL).
     *
     * @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 setupInterfaceForClientInScanMode(
            @NonNull InterfaceCallback interfaceCallback) {
        synchronized (mLock) {
            //启动vendor HAL
            if (!startHal()) {
                Log.e(TAG, "Failed to start Hal");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA_FOR_SCAN);
            if (iface == null) {
                Log.e(TAG, "Failed to allocate new STA iface");
                return null;
            }
            iface.externalListener = interfaceCallback;
            iface.name = createStaIface(iface);
            if (TextUtils.isEmpty(iface.name)) {
                Log.e(TAG, "Failed to create iface in vendor HAL");
                mIfaceMgr.removeIface(iface.id);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            if (!mWifiCondManager.setupInterfaceForClientMode(iface.name, Runnable::run,
                    new NormalScanEventCallback(iface.name),
                    new PnoScanEventCallback(iface.name))) {
                Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
                return null;
            }
            iface.networkObserver = new NetworkObserverInternal(iface.id);
            if (!registerNetworkObserver(iface.networkObserver)) {
                Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
                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));
            Log.i(TAG, "Successfully setup " + iface);

            iface.featureSet = getSupportedFeatureSetInternal(iface.name);
            return iface.name;
        }
    }

这个地方也是和Q版本相异的地方,Q版本在这个地方会启动wpa_supplicant,而R版本没有。下面讲一下R版本启动wpa_supplicant的逻辑。

3.switchClientModeManagerRole

这个也就是之前在第二节中所遗留的函数。

    /**
     * Method to enable a new client mode manager.
     */
    private boolean startClientModeManager() {
        Log.d(TAG, "Starting ClientModeManager");
        ClientListener listener = new ClientListener();
        ClientModeManager manager = mWifiInjector.makeClientModeManager(listener);
        listener.setActiveModeManager(manager);
        manager.start();
        if (!switchClientModeManagerRole(manager)) {
            return false;
        }
        mActiveModeManagers.add(manager);
        return true;
    }
    /**
     * Method to switch a client mode manager mode of operation (from ScanOnly To Connect &
     * vice-versa) based on the toggle state.
     */
    private boolean switchClientModeManagerRole(@NonNull ClientModeManager modeManager) {
        if (mSettingsStore.isWifiToggleEnabled()) {
            modeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY);
        } else if (checkScanOnlyModeAvailable()) {
            modeManager.setRole(ActiveModeManager.ROLE_CLIENT_SCAN_ONLY);
        } else {
            Log.e(TAG, "Something is wrong, no client mode toggles enabled");
            return false;
        }
        return true;
    }
    public void setRole(@Role int role) {
        Preconditions.checkState(CLIENT_ROLES.contains(role));
        if (role == ROLE_CLIENT_SCAN_ONLY) {
            mTargetRole = role;
            // Switch client mode manager to scan only mode.
            //给ClientModeStateMachine发送CMD_SWITCH_TO_SCAN_ONLY_MODE
            mStateMachine.sendMessage(ClientModeStateMachine.CMD_SWITCH_TO_SCAN_ONLY_MODE);
        } else if (CLIENT_CONNECTIVITY_ROLES.contains(role)) {
            mTargetRole = role;
            // Switch client mode manager to connect mode.
            //给ClientModeStateMachine发送CMD_SWITCH_TO_CONNECT_MODE
            mStateMachine.sendMessage(ClientModeStateMachine.CMD_SWITCH_TO_CONNECT_MODE, role);
        }
    }

现在也就是判断setRole传进来的role值是多少了?

    /**
     * Method to switch a client mode manager mode of operation (from ScanOnly To Connect &
     * vice-versa) based on the toggle state.
     */
    private boolean switchClientModeManagerRole(@NonNull ClientModeManager modeManager) {
        if (mSettingsStore.isWifiToggleEnabled()) {
            //很明显走进了这里,当然也可以加log来验证
            modeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY);
        } else if (checkScanOnlyModeAvailable()) {
            modeManager.setRole(ActiveModeManager.ROLE_CLIENT_SCAN_ONLY);
        } else {
            Log.e(TAG, "Something is wrong, no client mode toggles enabled");
            return false;
        }
        return true;
    }

    // ClientModeManager, primary STA, will respond to public APIs
    int ROLE_CLIENT_PRIMARY = 2;

    /** List of Client roles that could initiate a wifi connection */
    List<Integer> CLIENT_CONNECTIVITY_ROLES = Arrays.asList(
            ROLE_CLIENT_PRIMARY,
            ROLE_CLIENT_SECONDARY,
            ROLE_CLIENT_LOCAL_ONLY);

CLIENT_CONNECTIVITY_ROLES.contains(role)的意思就是当前的role值是否包含在CLIENT_CONNECTIVITY_ROLES里,我们也可以看到是包含的。所以最终会向ClientModeStateMachine发送CMD_SWITCH_TO_CONNECT_MODE

从下面的log可以指导进入了StarState.

07-27 11:41:42.327 D/WifiClientModeManager( 1675): entering StartedState

        private class StartedState extends State {

            @Override
            public void enter() {
                Log.d(TAG, "entering StartedState");
                mIfaceIsUp = false;
                onUpChanged(mWifiNative.isInterfaceUp(mClientInterfaceName));
            }

            @Override
            public boolean processMessage(Message message) {
                switch(message.what) {
                    case CMD_START:
                        // Already started, ignore this command.
                        break;
                    case CMD_SWITCH_TO_CONNECT_MODE:
                        mRole = message.arg1; // could be any one of possible connect mode roles.
                        //广播wifi状态更新
                        updateConnectModeState(WifiManager.WIFI_STATE_ENABLING,
                                WifiManager.WIFI_STATE_DISABLED);
                        //这个函数就开始启动wpa_supplicant了
                        if (!mWifiNative.switchClientInterfaceToConnectivityMode(
                                mClientInterfaceName)) {
                            updateConnectModeState(WifiManager.WIFI_STATE_UNKNOWN,
                                    WifiManager.WIFI_STATE_ENABLING);
                            updateConnectModeState(WifiManager.WIFI_STATE_DISABLED,
                                    WifiManager.WIFI_STATE_UNKNOWN);
                            mModeListener.onStartFailure();
                            break;
                        }
                        transitionTo(mConnectModeState);
                        break;

4.switchClientInterfaceToConnectivityMode

    /**
     * Switches an existing Client mode interface from scan mode
     * {@link Iface#IFACE_TYPE_STA_FOR_SCAN} to connectivity mode
     * {@link Iface#IFACE_TYPE_STA_FOR_CONNECTIVITY}.
     *
     * @param ifaceName Name of the interface.
     * @return true if the operation succeeded, false if there is an error or the iface is already
     * in scan mode.
     */
    public boolean switchClientInterfaceToConnectivityMode(@NonNull String ifaceName) {
        synchronized (mLock) {
            final Iface iface = mIfaceMgr.getIface(ifaceName);
            if (iface == null) {
                Log.e(TAG, "Trying to switch to connectivity mode on an invalid iface="
                        + ifaceName);
                return false;
            }
            if (iface.type == Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY) {
                Log.e(TAG, "Already in connectivity mode on iface=" + ifaceName);
                return true;
            }
            if (!startSupplicant()) {
                Log.e(TAG, "Failed to start supplicant");
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return false;
            }
            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return false;
            }
            iface.type = Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY;
            iface.featureSet = getSupportedFeatureSetInternal(iface.name);
            Log.i(TAG, "Successfully switched to connectivity mode on iface=" + iface);
            return true;
        }
    }

    private boolean startSupplicant() {
        synchronized (mLock) {
            if (!mIfaceMgr.hasAnyStaIfaceForConnectivity()) {
                if (!startAndWaitForSupplicantConnection()) {
                    Log.e(TAG, "Failed to connect to supplicant");
                    return false;
                }
                if (!mSupplicantStaIfaceHal.registerDeathHandler(
                        new SupplicantDeathHandlerInternal())) {
                    Log.e(TAG, "Failed to register supplicant death handler");
                    return false;
                }
            }
            return true;
        }
    }
    private boolean startAndWaitForSupplicantConnection() {
        // Start initialization if not already started.
        if (!mSupplicantStaIfaceHal.isInitializationStarted()
                && !mSupplicantStaIfaceHal.initialize()) {
            return false;
        }
        if (!mSupplicantStaIfaceHal.startDaemon()) {
            Log.e(TAG, "Failed to startup supplicant");
            return false;
        }
        boolean connected = false;
        int connectTries = 0;
        while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
            // Check if the initialization is complete.
            connected = mSupplicantStaIfaceHal.isInitializationComplete();
            if (connected) {
                break;
            }
            try {
                Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
            } catch (InterruptedException ignore) {
            }
        }
        return connected;
    }
    /**
     * Start the supplicant daemon for V1_1 service.
     *
     * @return true on success, false otherwise.
     */
    private boolean startDaemon_V1_1() {
        synchronized (mLock) {
            try {
                // This should startup supplicant daemon using the lazy start HAL mechanism.
                getSupplicantMockableV1_1();
            } catch (RemoteException e) {
                Log.e(TAG, "Exception while trying to start supplicant: "
                        + e);
                supplicantServiceDiedHandler(mDeathRecipientCookie);
                return false;
            } catch (NoSuchElementException e) {
                // We're starting the daemon, so expect |NoSuchElementException|.
                Log.d(TAG, "Successfully triggered start of supplicant using HIDL");
            }
            return true;
        }
    }
    /**
     * Start the supplicant daemon.
     *
     * @return true on success, false otherwise.
     */
    public boolean startDaemon() {
        synchronized (mLock) {
            if (isV1_1()) {
                Log.i(TAG, "Starting supplicant using HIDL");
                return startDaemon_V1_1();
            } else {
                Log.i(TAG, "Starting supplicant using init");
                mFrameworkFacade.startSupplicant();
                return true;
            }
        }
    }

这边可以从log看到是走的getSupplicantMockableV1_1()

剑气纵横三万里

“为什么要努力?” “想去的地方很远,想要的东西很贵,喜欢的人很优秀,父母的白发,朋友的约定,周围人的嘲笑,以及,天生傲骨。”

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

相关推荐

暂无内容!