赞
踩
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
.
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
类.
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
的全局变量.
wifi模块状态机,前文中已经出镜了很多次,状态机在系统的wifi
,Bluetooth
等模块都有很广泛的应用.
状态机模块应该是在不同的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()
函数之间兜兜转转.
@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
中去.
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()); }}); ... } ... }
我们以开机之后检查wifi状态是否在关机前是开启状态,然后打开wifi的例子:
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
//检查并启动wifi
mImpl.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 */ } } }
/** * 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; }
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()
/**
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;
}
/**
总结
--
上面的流程中其实从最开始的`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
……
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 源码分析——图片加载流程
1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》
从一个膜拜大神的 Demo 开始
Kotlin 写 Gradle 脚本是一种什么体验?
Kotlin 编程的三重境界
Kotlin 高阶函数
Kotlin 泛型
Kotlin 扩展
Kotlin 委托
协程“不为人知”的调试技巧
图解协程:suspend
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使用指南
1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习
1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)
…
1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……
一、面试合集
二、源码解析合集
三、开源框架合集
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取【保证100%免费】↓↓↓
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。