我是靠谱客的博主 默默小天鹅,这篇文章主要介绍Android WIFI 模块解析(1),现在分享给大家,希望可以做个参考。

SystemServer

android的大部分服务都是在SystemServer中孵化出来的,wifi也不例外,从SystemServer注册WifiService开始梳理.

//wifi 扫描 和获取相关功能 Service
private static final String WIFI_SERVICE_CLASS =
        "com.android.server.wifi.WifiService";
//wifi 感知相关功能Service
private static final String WIFI_AWARE_SERVICE_CLASS =
        "com.android.server.wifi.aware.WifiAwareService";
//wifi P2P  相关功能 Service
private static final String WIFI_P2P_SERVICE_CLASS =
        "com.android.server.wifi.p2p.WifiP2pService"; 
if (context.getPackageManager().hasSystemFeature(
        PackageManager.FEATURE_WIFI)) {
    // Wifi Service must be started first for wifi-related services.
    traceBeginAndSlog("StartWifi");
    mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
    traceEnd();
    traceBeginAndSlog("StartWifiScanning");
    mSystemServiceManager.startService(
            "com.android.server.wifi.scanner.WifiScanningService");
    traceEnd();
} 

在SystemServer之中主要工作就是定义WifiService,启动了WifiService和WifiScanningService.

相关代码路径

  • com.android.server.SystemServer

相关参考文档

  • WifiService
  • WifiP2pService
  • WifiAwareService

WifiService

public final class WifiService extends SystemService {

    final WifiServiceImpl mImpl;

    public WifiService(Context context) {
        super(context);
        //创建具体的事务类
        mImpl = new WifiServiceImpl(context, new WifiInjector(context), new WifiAsyncChannel(TAG));
    }

    @Override
    public void onStart() {
        Log.i(TAG, "Registering " + Context.WIFI_SERVICE);
        //绑定事务类
        publishBinderService(Context.WIFI_SERVICE, mImpl);
    }

    @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            mImpl.checkAndStartWifi();
        }
    }
    ...
} 

onBootPhase随着系统服务的进程会不断的调用到具体的Service中.在具体的Service判断进度值执行逻辑.此处调用逻辑主要是检查wifi模块是否需要启动,如果需要启动就启动wifi模块.总体来说WifiService的主要作用就是绑定了WifiServiceImpl类.

WifiServiceImpl

public class WifiServiceImpl extends IWifiManager.Stub {
   ...
} 

可以看到WifiServiceImpl类继承了IWifiManager.Stub函数,熟悉aidl的已经知道它的内部主要实现的函数在aidl文件中已经定义了. 对外部暴露的类就是我们在应用中常用的WifiManager类.

往下看,首先看WifiServiceImpl的构造函数

public WifiServiceImpl(Context context, WifiInjector wifiInjector, AsyncChannel asyncChannel) {
    mContext = context;
    mWifiInjector = wifiInjector;
    mClock = wifiInjector.getClock();

    mFacade = mWifiInjector.getFrameworkFacade();
    mWifiMetrics = mWifiInjector.getWifiMetrics();
    mTrafficPoller = mWifiInjector.getWifiTrafficPoller();
    mUserManager = mWifiInjector.getUserManager();
    mCountryCode = mWifiInjector.getWifiCountryCode();
    mWifiStateMachine = mWifiInjector.getWifiStateMachine();
    mWifiStateMachinePrime = mWifiInjector.getWifiStateMachinePrime();
    mWifiStateMachine.enableRssiPolling(true);
    mScanRequestProxy = mWifiInjector.getScanRequestProxy();
    mSettingsStore = mWifiInjector.getWifiSettingsStore();
    mPowerManager = mContext.getSystemService(PowerManager.class);
    mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
    mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
    mWifiLockManager = mWifiInjector.getWifiLockManager();
    mWifiMulticastLockManager = mWifiInjector.getWifiMulticastLockManager();
    HandlerThread wifiServiceHandlerThread = mWifiInjector.getWifiServiceHandlerThread();
    mClientHandler = new ClientHandler(TAG, wifiServiceHandlerThread.getLooper());
    mWifiStateMachineHandler = new WifiStateMachineHandler(TAG,
            wifiServiceHandlerThread.getLooper(), asyncChannel);
    mWifiController = mWifiInjector.getWifiController();
    mWifiBackupRestore = mWifiInjector.getWifiBackupRestore();
    mWifiApConfigStore = mWifiInjector.getWifiApConfigStore();
    mPermissionReviewRequired = Build.PERMISSIONS_REVIEW_REQUIRED
            || context.getResources().getBoolean(
            com.android.internal.R.bool.config_permissionReviewRequired);
    mWifiPermissionsUtil = mWifiInjector.getWifiPermissionsUtil();
  ...
} 

构造函数中有三个参数

  • Context 这个大家很熟悉

  • WifiInjector wifi模块相关的对象的初始化工作都在这个类里进行.没有做其他多余的事情. 包括状态机的初始化就在这里进行初始化,然后通过get函数赋值给WifiServiceImpl中.

public WifiInjector(Context context) {
    if (context == null) {
        throw new IllegalStateException(
                "WifiInjector should not be initialized with a null Context.");
    }

    if (sWifiInjector != null) {
        throw new IllegalStateException(
                "WifiInjector was already created, use getInstance instead.");
    }

    sWifiInjector = this;

    mContext = context;
    mUseRealLogger = mContext.getResources().getBoolean(
            R.bool.config_wifi_enable_wifi_firmware_debugging);
    mSettingsStore = new WifiSettingsStore(mContext);
    mWifiPermissionsWrapper = new WifiPermissionsWrapper(mContext);
    mNetworkScoreManager = mContext.getSystemService(NetworkScoreManager.class);
    mWifiNetworkScoreCache = new WifiNetworkScoreCache(mContext);
    mNetworkScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
            mWifiNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_NONE);
    mWifiPermissionsUtil = new WifiPermissionsUtil(mWifiPermissionsWrapper, mContext,
            mSettingsStore, UserManager.get(mContext), this);
    ...
    mWifiServiceHandlerThread = new HandlerThread("WifiService");
    mWifiServiceHandlerThread.start();
    mWifiStateMachineHandlerThread = new HandlerThread("WifiStateMachine");
    mWifiStateMachineHandlerThread.start();
    Looper wifiStateMachineLooper = mWifiStateMachineHandlerThread.getLooper();
    mCarrierNetworkConfig = new CarrierNetworkConfig(mContext,
        mWifiServiceHandlerThread.getLooper(), mFrameworkFacade);
    WifiAwareMetrics awareMetrics = new WifiAwareMetrics(mClock);
    RttMetrics rttMetrics = new RttMetrics(mClock);
    mWifiMetrics = new WifiMetrics(mClock, wifiStateMachineLooper, awareMetrics, rttMetrics);
    // Modules interacting with Native.  与Native 模块交互的对象,后文有见到
    mWifiMonitor = new WifiMonitor(this);
    mHalDeviceManager = new HalDeviceManager(mClock);
    mWifiVendorHal =
            new WifiVendorHal(mHalDeviceManager, mWifiStateMachineHandlerThread.getLooper());
    mSupplicantStaIfaceHal = new SupplicantStaIfaceHal(mContext, mWifiMonitor);
    mHostapdHal = new HostapdHal(mContext);
    mWificondControl = new WificondControl(this, mWifiMonitor, mCarrierNetworkConfig);
    mNwManagementService = INetworkManagementService.Stub.asInterface(
            ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
    // wifiNative 对象在此创建.
    mWifiNative = new WifiNative(
            mWifiVendorHal, mSupplicantStaIfaceHal, mHostapdHal, mWificondControl,
            mWifiMonitor, mNwManagementService, mPropertyService, mWifiMetrics);
    ...

    // Now get instances of all the objects that depend on the HandlerThreads
    mTrafficPoller = new WifiTrafficPoller(mContext, mWifiServiceHandlerThread.getLooper(),
            mWifiNative);
    mCountryCode = new WifiCountryCode(mWifiNative,
            SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
            mContext.getResources()
                    .getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss));
    mWifiApConfigStore = new WifiApConfigStore(mContext, mBackupManagerProxy);

    // WifiConfigManager/Store objects and their dependencies.
    // New config store
    mWifiKeyStore = new WifiKeyStore(mKeyStore);
    mWifiConfigStore = new WifiConfigStore(
            mContext, wifiStateMachineLooper, mClock,
            WifiConfigStore.createSharedFile());
    ...
    mWifiConfigStoreLegacy = new WifiConfigStoreLegacy(
            mWifiNetworkHistory, mWifiNative, new WifiConfigStoreLegacy.IpConfigStoreWrapper(),
            new LegacyPasspointConfigParser());
    // Config Manager
    mWifiConfigManager = new WifiConfigManager(mContext, mClock,
            UserManager.get(mContext), TelephonyManager.from(mContext),
            mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy, mWifiPermissionsUtil,
            mWifiPermissionsWrapper, new NetworkListStoreData(mContext),
            new DeletedEphemeralSsidsStoreData());
    mWifiMetrics.setWifiConfigManager(mWifiConfigManager);
    mWifiConnectivityHelper = new WifiConnectivityHelper(mWifiNative);
    mConnectivityLocalLog = new LocalLog(ActivityManager.isLowRamDeviceStatic() ? 256 : 512);
    mScoringParams = new ScoringParams(mContext, mFrameworkFacade,
            new Handler(wifiStateMachineLooper));
    mWifiMetrics.setScoringParams(mScoringParams);
    mWifiNetworkSelector = new WifiNetworkSelector(mContext, mScoringParams,
            mWifiConfigManager, mClock,
            mConnectivityLocalLog);
    mWifiMetrics.setWifiNetworkSelector(mWifiNetworkSelector);
    ...
} 
  • AsyncChannel 这个也是一个比较重要的概念,简单的说就是在两个Handle之间处理异步消息同步消息使用.在这里是与wifi状态机中SmHandler中建立一个通道.
/**
 * Handles interaction with WifiStateMachine
 */
private class WifiStateMachineHandler extends WifiHandler {
    private AsyncChannel mWsmChannel;

    WifiStateMachineHandler(String tag, Looper looper, AsyncChannel asyncChannel) {
        super(tag, looper);
        mWsmChannel = asyncChannel;
        //链接
        mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
                if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                      //链接成功 赋值
                    mWifiStateMachineChannel = mWsmChannel;
                } else {
                    Slog.e(TAG, "WifiStateMachine connection failure, error=" + msg.arg1);
                    // 链接失败,置空
                    mWifiStateMachineChannel = null;
                }
                break;
            }
            case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
                Slog.e(TAG, "WifiStateMachine channel lost, msg.arg1 =" + msg.arg1);
                mWifiStateMachineChannel = null;  // 置空
                //Re-establish connection to state machine  断开 重连
                mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
                break;
            }
            default: {
                Slog.d(TAG, "WifiStateMachineHandler.handleMessage ignoring msg=" + msg);
                break;
            }
        }
    }
} 

可以看到构造函数中主要就是做一些全局属性的赋值.具体初始化的操作在WifiInjector中,通过get函数赋值给WifiServiceImpl的全局变量.

WifiStateMachine

wifi模块状态机,前文中已经出镜了很多次,状态机在系统的wifi,Bluetooth等模块都有很广泛的应用.

  • Android 4.4 WifiStateMachine状态机

20190504201521921.jpg

  • Android 9.0 WifiStateMachine状态机

20190504202816489.jpg

状态机模块应该是在不同的Android版本之间变动最大的模块,中间经历了优化层级,状态合并,p2p等功能拆分等变动.

简单的描述一下状态机是一个什么功能,举个例子:

1:假如我们接到一个需求,开发一个自动回应系统,按某些数字之后,有自动回复,或者给用户提供某些服务,c服务需要你先进入B状态,用户在你提供C服务的时候,有需要你提供E服务,E服务的前置服务是D服务,假如不够智能的话那就需要4步 C->B->D->E . 那么状态机器在你由C切换E的时候,直接帮助你把省略这些繁琐的操作,直接默认执行了这些状态的进入和退出的代码.

  • 如果需要完全的理解状态机的完整概念,请自行百度状态机.有很多文章讲这个东西.

那么回到wifi模块的状态机中,先看构造函数

public WifiStateMachine(Context context, FrameworkFacade facade, Looper looper,
                        UserManager userManager, WifiInjector wifiInjector,
                        BackupManagerProxy backupManagerProxy, WifiCountryCode countryCode,
                        WifiNative wifiNative,
                        WrongPasswordNotifier wrongPasswordNotifier,
                        SarManager sarManager) {
    super("WifiStateMachine", looper);
    mWifiInjector = wifiInjector;
    mWifiMetrics = mWifiInjector.getWifiMetrics();
    mClock = wifiInjector.getClock();
    mPropertyService = wifiInjector.getPropertyService();
    mBuildProperties = wifiInjector.getBuildProperties();
    mContext = context;
    mFacade = facade;
    mWifiNative = wifiNative;
    mBackupManagerProxy = backupManagerProxy;
    mWrongPasswordNotifier = wrongPasswordNotifier;
    mSarManager = sarManager;
    //赋值操作
    // TODO refactor WifiNative use of context out into it's own class
    mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
    mBatteryStats = IBatteryStats.Stub.asInterface(mFacade.getService(
            BatteryStats.SERVICE_NAME));
    mWifiStateTracker = wifiInjector.getWifiStateTracker();
    IBinder b = mFacade.getService(Context.NETWORKMANAGEMENT_SERVICE);

    mP2pSupported = mContext.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_WIFI_DIRECT);

    mWifiPermissionsUtil = mWifiInjector.getWifiPermissionsUtil();
    mWifiConfigManager = mWifiInjector.getWifiConfigManager();

    mPasspointManager = mWifiInjector.getPasspointManager();

    mWifiMonitor = mWifiInjector.getWifiMonitor();
    mWifiDiagnostics = mWifiInjector.getWifiDiagnostics();
    mScanRequestProxy = mWifiInjector.getScanRequestProxy();
    mWifiPermissionsWrapper = mWifiInjector.getWifiPermissionsWrapper();

    mWifiInfo = new ExtendedWifiInfo();
    mSupplicantStateTracker =
            mFacade.makeSupplicantStateTracker(context, mWifiConfigManager, getHandler());

    mLinkProperties = new LinkProperties();
    mMcastLockManagerFilterController = new McastLockManagerFilterController();

    mNetworkInfo.setIsAvailable(false);
    mLastBssid = null;
    mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
    mLastSignalLevel = -1;

      ...

    mUserWantsSuspendOpt.set(mFacade.getIntegerSetting(mContext,
            Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1);

    updateConnectedMacRandomizationSetting();

    PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
    mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getName());

    mSuspendWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WifiSuspend");
    mSuspendWakeLock.setReferenceCounted(false);

    mTcpBufferSizes = mContext.getResources().getString(
            com.android.internal.R.string.config_wifi_tcp_buffers);

    // CHECKSTYLE:OFF IndentationCheck
    addState(mDefaultState);  //添加wifi模块各种状态 ,状态机就在这里
        addState(mConnectModeState, mDefaultState);
            addState(mL2ConnectedState, mConnectModeState);
                addState(mObtainingIpState, mL2ConnectedState);
                addState(mConnectedState, mL2ConnectedState);
                addState(mRoamingState, mL2ConnectedState);
            addState(mDisconnectingState, mConnectModeState);
            addState(mDisconnectedState, mConnectModeState);
    // CHECKSTYLE:ON IndentationCheck

    setInitialState(mDefaultState);

    setLogRecSize(NUM_LOG_RECS_NORMAL);
    setLogOnlyTransitions(false);

    //start the state machine//启动状态机
    start();

    // Learn the initial state of whether the screen is on.
    // We update this field when we receive broadcasts from the system.
    handleScreenStateChanged(powerManager.isInteractive());
} 

然后wifi模块的各个状态的转换之间的逻辑就在DefaultState这些状态的enter(),exit()和processMessage()函数之间兜兜转转.

WifiManager (应用层使用看这里)

@SystemService(Context.WIFI_SERVICE)  
public class WifiManager {
    
    /**
     * Create a new WifiManager instance.
     * Applications will almost always want to use    // 这里告诉我们应用想要使用 通过 下面的方式去获取
     * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
     * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}.
     * @param context the application context
     * @param service the Binder interface
     * @hide - hide this because it takes in a parameter of type IWifiManager, which
     * is a system private class.   // 这里使用了hide的方式去隐藏次函数,告诉我们使用这是一个系统私有类
     */
    public WifiManager(Context context, IWifiManager service, Looper looper) {
        mContext = context;
        mService = service;
        mLooper = looper;
        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
    }
} 

按照惯例我们贴出了它的构造函数,如果是上层App应用去简单的使用wifi模块的相关功能,那么看懂上面的代码就可以,看懂了上面的代码,我们就知道怎么去获取WifiManager对象.

WifiManager mWifiManager;
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); 

后面我们就需要根据 WifiManager提供的函数去设计我们的上层逻辑即可.同样具体的实现或逻辑判断是放在继承IWifiManager.Stub的WifiServiceImpl中去.

  • WifiManager注册
final class SystemServiceRegistry {
    ...
    static {
        ...
        registerService(Context.WIFI_SERVICE, WifiManager.class,
                new CachedServiceFetcher<WifiManager>() {
            @Override
            public WifiManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_SERVICE);
                IWifiManager service = IWifiManager.Stub.asInterface(b);
                return new WifiManager(ctx.getOuterContext(), service,
                        ConnectivityThread.getInstanceLooper());
            }});
        ...
    }
    ...
} 

实际例子(开机 checkAndStartWifi())

我们以开机之后检查wifi状态是否在关机前是开启状态,然后打开wifi的例子:

1: WifiService.onBootPhase()

 @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            //检查并启动wifi
            mImpl.checkAndStartWifi();
        }
    } 

2: WifiServiceImpl.checkAndStartWifi()

/**
 * Check if we are ready to start wifi.
 *
 * First check if we will be restarting system services to decrypt the device. If the device is
 * not encrypted, check if Wi-Fi needs to be enabled and start if needed
 *
 * This function is used only at boot time.
 */
public void checkAndStartWifi() {
    // First check if we will end up restarting WifiService
    if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
        Log.d(TAG, "Device still encrypted. Need to restart SystemServer.  Do not start wifi.");
        return;
    }

    // Check if wi-fi needs to be enabled 
    // 检查是否需要打开wifi.取决于关机时wifi状态
    boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
    Slog.i(TAG, "WifiService starting up with Wi-Fi " +
            (wifiEnabled ? "enabled" : "disabled"));
        ... //注册广播监听
    registerForScanModeChange();
        ...
    // Adding optimizations of only receiving broadcasts when wifi is enabled
    // can result in race conditions when apps toggle wifi in the background
    // without active user involvement. Always receive broadcasts.
    registerForBroadcasts();
    mInIdleMode = mPowerManager.isDeviceIdleMode();

    if (!mWifiStateMachine.syncInitialize(mWifiStateMachineChannel)) {
        Log.wtf(TAG, "Failed to initialize WifiStateMachine");
    }
    //关于wifi操作模式的状态机启动. 例如 飞行模式,wifi热点模式 等等.
    mWifiController.start();

    // If we are already disabled (could be due to airplane mode), avoid changing persist
    // state here
    if (wifiEnabled) {
        try {
            //如果上次wifi是开的,设置wifi开关.
            setWifiEnabled(mContext.getPackageName(), wifiEnabled);
        } catch (RemoteException e) {
            /* ignore - local call */
        }
    }
} 

3: 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 {
        
        //检查应用权限
    if (enforceChangePermission(packageName) != MODE_ALLOWED) {
        return false;
    }

    Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
                + ", uid=" + Binder.getCallingUid() + ", package=" + packageName);
    mLog.info("setWifiEnabled package=% uid=% enable=%").c(packageName)
            .c(Binder.getCallingUid()).c(enable).flush();
    //检查网络权限
    boolean isFromSettings = checkNetworkSettingsPermission(
            Binder.getCallingPid(), Binder.getCallingUid());

    // If Airplane mode is enabled, only Settings is allowed to toggle Wifi
    if (mSettingsStore.isAirplaneModeOn() && !isFromSettings) {
        mLog.info("setWifiEnabled in Airplane mode: only Settings can enable wifi").flush();
        return false;
    }
    // 各种检查wifi 状态,如果已经打开了,return true.
      ...

    //权限审核.
    if (mPermissionReviewRequired) {
        final int wiFiEnabledState = getWifiEnabledState();
        if (enable) {
            if (wiFiEnabledState == WifiManager.WIFI_STATE_DISABLING
                    || wiFiEnabledState == WifiManager.WIFI_STATE_DISABLED) {
                if (startConsentUi(packageName, Binder.getCallingUid(),
                        WifiManager.ACTION_REQUEST_ENABLE)) {
                    return true;
                }
            }
        } else if (wiFiEnabledState == WifiManager.WIFI_STATE_ENABLING
                || wiFiEnabledState == WifiManager.WIFI_STATE_ENABLED) {
            if (startConsentUi(packageName, Binder.getCallingUid(),
                    WifiManager.ACTION_REQUEST_DISABLE)) {
                return true;
            }
        }
    }
    // 发送消息
    mWifiController.sendMessage(CMD_WIFI_TOGGLED);
    return true;
} 

4 WifiController

mWifiController这个对象在wifiServiceImpl的构造函数中赋值的,我们简单看下它的构造函数,看一下CMD_WIFI_TOGGLED状态由谁接收

/**
 * 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 {
    

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

setLogRecSize(100);
setLogOnlyTransitions(false);

// register for state updates via callbacks (vs the intents registered below)
mWifiStateMachinePrime.registerScanOnlyCallback(mScanOnlyModeCallback);
mWifiStateMachinePrime.registerClientModeCallback(mClientModeCallback);

...
readWifiReEnableDelay();

}

*   checkScanOnlyModeAvailable()


private boolean checkScanOnlyModeAvailable() {
// first check if Location service is disabled, if so return false
// 首先看定位服务是否关闭,如果关闭,直接返回false.
if (mSettingsStore.getLocationModeSetting(mContext)
== Settings.Secure.LOCATION_MODE_OFF) {
return false;
}

// 这个的基本通过这个值来控制 Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE 默认值为0 就是不打开
return mSettingsStore.isScanAlwaysAvailable();

}

由此得知默认状态为 `mStaDisabledState`

### 5: WifiController.StaDisabledState


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();
}
@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;
        ...
    }
    return HANDLED;
}

private boolean doDeferEnable(Message msg) {
    long delaySoFar = SystemClock.elapsedRealtime() - mDisabledTimestamp;
    if (delaySoFar >= mReEnableDelayMillis) {
        return false;
    }

    log("WifiController msg " + msg + " deferred for " +
            (mReEnableDelayMillis - delaySoFar) + "ms");

    // need to defer this action.
    Message deferredMsg = obtainMessage(CMD_DEFERRED_TOGGLE);
    deferredMsg.obj = Message.obtain(msg);
    deferredMsg.arg1 = ++mDeferredEnableSerialNumber;
    sendMessageDelayed(deferredMsg, mReEnableDelayMillis - delaySoFar + DEFER_MARGIN_MS);
    return true;
}

}

### 6: WifiController.DeviceActiveState


/**

  • Parent: StaEnabledState
    *

  • TODO (b/79209870): merge DeviceActiveState and StaEnabledState into a single state
    */
    class DeviceActiveState extends State {
    @Override
    public void enter() {
    //这里
    mWifiStateMachinePrime.enterClientMode();
    //无效的,所以固定的写了false. 可能各个版本不同
    mWifiStateMachine.setHighPerfModeEnabled(false);
    }

    @Override
    public boolean processMessage(Message msg) {
    …
    return NOT_HANDLED;
    }
    }

### 7: WifiStateMachinePrime.enterClientMode()


/**

  • 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 是个什么东西
mModeStateMachine.sendMessage(newMode);
}

### 8: ModeStateMachine

`ModeStateMachine`也是继承`StateMachine`,内部也是维和了几个状态的状态机


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

    Log.d(TAG, "Starting Wifi in WifiDisabledState");
    //初始状态,我们看 WifiDisabledState 状态中是怎么处理的
    setInitialState(mWifiDisabledState);
    start();
}
    //这里切换状态
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;
}

}

### 9: WifiDisabledState


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);
    //这里调用切换状态 发送的消息是 CMD_START_CLIENT_MODE. 切换到 mClientModeActiveState
    if (checkForAndHandleModeChange(message)) {
        return HANDLED;
    }
    return NOT_HANDLED;
}

@Override
public void exit() {
    // do not have an active mode manager...  nothing to clean up
}

}

### 10: ClientModeActiveState


class ClientModeActiveState extends ModeActiveState {
ClientListener mListener;
private class ClientListener implements ClientModeManager.Listener {
@Override
public void onStateChanged(int state) {
// make sure this listener is still active
if (this != mListener) {
Log.d(TAG, “Client mode state change from previous manager”);
return;
}

        Log.d(TAG, "State changed from client mode. state = " + state);

        if (state == WifiManager.WIFI_STATE_UNKNOWN) {
            // error while setting up client mode or an unexpected failure.
            mModeStateMachine.sendMessage(CMD_CLIENT_MODE_FAILED, this);
        } else if (state == WifiManager.WIFI_STATE_DISABLED) {
            // client mode stopped
            mModeStateMachine.sendMessage(CMD_CLIENT_MODE_STOPPED, this);
        } else if (state == WifiManager.WIFI_STATE_ENABLED) {
            // client mode is ready to go
            Log.d(TAG, "client mode active");
        } else {
            // only care if client mode stopped or started, dropping
        }
    }
}

@Override
public void enter() {
    Log.d(TAG, "Entering ClientModeActiveState");
    //进入状态
    mListener = new ClientListener();
    // 这里创建一个ClientModeManager,我们接着看 ClientModeManager
    mManager = mWifiInjector.makeClientModeManager(mListener);
    mManager.start();
    mActiveModeManagers.add(mManager);

    updateBatteryStatsWifiState(true);
}

@Override
public void exit() {
    super.exit();
    mListener = null;
}

@Override
public boolean processMessage(Message message) {
    if (checkForAndHandleModeChange(message)) {
        return HANDLED;
    }
   ...
}

}

### 11:ClientModeManager


/**

  • Manager WiFi in Client Mode where we connect to configured networks.
    */
    public class ClientModeManager implements ActiveModeManager {

    private static final String TAG = “WifiClientModeManager”;
    private final ClientModeStateMachine mStateMachine;
    …
    ClientModeManager(Context context, @NonNull Looper looper, WifiNative wifiNative,
    Listener listener, WifiMetrics wifiMetrics, ScanRequestProxy scanRequestProxy,
    WifiStateMachine wifiStateMachine) {
    mContext = context;
    mWifiNative = wifiNative;
    mListener = listener;
    mWifiMetrics = wifiMetrics;
    mScanRequestProxy = scanRequestProxy;
    mWifiStateMachine = wifiStateMachine;
    mStateMachine = new ClientModeStateMachine(looper);
    }

    /**
     * Start client mode.
     */
    public void start() {
        // 这里看名字就知道,又是一个状态机 ,发送CMD_START 指令
        mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
    }
    ...
    
    

}

### 12: ClientModeStateMachine


private class ClientModeStateMachine extends StateMachine {
// Commands for the state machine.
public static final int CMD_START = 0;
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;
//只有两种状态
private final State mIdleState = new IdleState();
private final State mStartedState = new StartedState();

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

    addState(mIdleState);
    addState(mStartedState);
    //默认状态为 mIdleState 
    setInitialState(mIdleState);
    start();
}

}

### 13: 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);
            //在这里 出现了总算是没有在跳转不同的状态机了.到了一个类似Native函数中. 
            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;
}

}

### 14: WifiNative

到这里就开始与hal层进行交互了,后续就在分一章在去分析后面的进程.


/**

  • Native calls for bring up/shut down of the supplicant daemon and for

  • sending requests to the supplicant daemon
    *

  • {@hide}
    */
    public class WifiNative {
    private static final String TAG = “WifiNative”;
    private final SupplicantStaIfaceHal mSupplicantStaIfaceHal;
    private final HostapdHal mHostapdHal;
    private final WifiVendorHal mWifiVendorHal;
    private final WificondControl mWificondControl;
    private final WifiMonitor mWifiMonitor;
    private final INetworkManagementService mNwManagementService;
    private final PropertyService mPropertyService;
    private final WifiMetrics mWifiMetrics;
    private boolean mVerboseLoggingEnabled = false;

    public WifiNative(WifiVendorHal vendorHal,
    SupplicantStaIfaceHal staIfaceHal, HostapdHal hostapdHal,
    WificondControl condControl, WifiMonitor wifiMonitor,
    INetworkManagementService nwService,
    PropertyService propertyService, WifiMetrics wifiMetrics) {
    mWifiVendorHal = vendorHal;
    mSupplicantStaIfaceHal = staIfaceHal;
    mHostapdHal = hostapdHal;
    mWificondControl = condControl;
    mWifiMonitor = wifiMonitor;
    mNwManagementService = nwService;
    mPropertyService = propertyService;
    mWifiMetrics = wifiMetrics;
    }

    /**

    • 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;
      }
      }
总结
--

上面的流程中其实从最开始的`SystemServer`中启动`wifiService`之后调用 checkAndStartWifi() 之后,中间就是各种状态判断,各种权限判断,各种状态同步的问题.具体的业务逻辑呢就是在不同的状态机中兜兜转转.我把中间兜兜转转的状态机用图画一下

### WifiController

// CHECKSTYLE:OFF IndentationCheck
addState(mDefaultState);
addState(mStaDisabledState, mDefaultState);
addState(mStaEnabledState, mDefaultState);
addState(mDeviceActiveState, mStaEnabledState);
addState(mStaDisabledWithScanState, mDefaultState);
addState(mEcmState, mDefaultState);
// CHECKSTYLE:ON IndentationCheck
if (checkScanOnlyModeAvailable()) {
setInitialState(mStaDisabledWithScanState);
} else {
setInitialState(mStaDisabledState);
}

![WifiController.jpg](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7cd634d8290648c693bc5eb228b3448c~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)

这里的流程就是从`StaDisabledState`切换到`DeviceActiveState`之后调用`enterClientMode()`进入 `ModeStateMachine`,也是一个状态机器如下图

### ModeStateMachine

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

Log.d(TAG, “Starting Wifi in WifiDisabledState”);
setInitialState(mWifiDisabledState);

![ModeStateMachine.jpg](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4d64fe1cd6954e62a39cdd22881d97b2~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)

这里的流程是从`WifiDisabledState`转到`ClientModeActiveState`.然后进入`ClientModeManager`,`ClientModeManager`中的`start()`启动了`ClientModeStateMachine`状态机 如下图

### ClientModeStateMachine

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

addState(mIdleState);
addState(mStartedState);

setInitialState(mIdleState);
start();

}

![ClientModeManager.jpg](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0d15f98b2d99447c9f724d8790fa73a1~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)

在`IdleState`调用`wifiNative`判断底层是否已经启动,启动成功之后就会转入`StartedState`.之后就是通过回调函数,或者`Handle`将wifi扫描结果和状态在一层层返回.

文末

要想成为架构师,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

一、架构师筑基必备技能

1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……

在这里插入图片描述

二、Android百大框架源码解析

1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程

在这里插入图片描述

三、Android性能优化实战解析

  • 腾讯Bugly:对字符串匹配算法的一点理解
  • 爱奇艺:安卓APP崩溃捕获方案——xCrash
  • 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 百度APP技术:Android H5首屏优化实践
  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 携程:从智行 Android 项目看组件化架构实践
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”?
  • …

在这里插入图片描述

四、高级kotlin强化实战

1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

在这里插入图片描述

五、Android高级UI开源框架进阶解密

1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
在这里插入图片描述

六、NDK模块开发

1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习

在这里插入图片描述

七、Flutter技术进阶

1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)
…
在这里插入图片描述

八、微信小程序开发

1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……

在这里插入图片描述

全套视频资料:

一、面试合集
在这里插入图片描述
二、源码解析合集

在这里插入图片描述
三、开源框架合集

在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取【保证100%免费】↓↓↓
在这里插入图片描述

最后

以上就是默默小天鹅最近收集整理的关于Android WIFI 模块解析(1)的全部内容,更多相关Android内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(267)

评论列表共有 0 条评论

立即
投稿
返回
顶部