Android Wifi 启动过程,AndroidP wifi启动流程
從AndroidO到AndroidP,Wifi架構(gòu)上還是發(fā)生了挺多變化的。接口上也在發(fā)生變化,所以網(wǎng)上的很多的流程梳理已經(jīng)跟當(dāng)前的代碼邏輯有一些差異了。不過還好,總體上,只要懂了一個版本的代碼,看其他版本問題已經(jīng)不是很大。
梳理還是簡單易懂為要務(wù)。
調(diào)用WifiManager中的setWifiEabled()開啟wifi:
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(getContext().getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
通過aidl調(diào)用到系統(tǒng)進(jìn)程中的服務(wù)類WifiServiceImpl.java中:
public synchronized boolean setWifiEnabled(String packageName, boolean enable)
throws RemoteException {
enforceChangePermission();
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;
}
// If SoftAp is enabled, only Settings is allowed to toggle wifi
boolean apEnabled =
mWifiStateMachine.syncGetWifiApState() != WifiManager.WIFI_AP_STATE_DISABLED;
if (apEnabled && !isFromSettings) {
mLog.info("setWifiEnabled SoftAp not disabled: only Settings can enable wifi").flush();
return false;
}
/*
* Caller might not have WRITE_SECURE_SETTINGS,
* only CHANGE_WIFI_STATE is enforced
*/
long ident = Binder.clearCallingIdentity();
try {
if (! mSettingsStore.handleWifiToggled(enable)) {
// Nothing to do if wifi cannot be toggled
return true;
}
} finally {
Binder.restoreCallingIdentity(ident);
}
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;
}
此段代碼邏輯中有涉及到權(quán)限檢測,以及wifi開關(guān)狀態(tài)保存等操作,最終調(diào)用到了如下方法:
mWifiController.sendMessage(CMD_WIFI_TOGGLED);
WifiController是一個狀態(tài)機(jī),接收到消息會根據(jù)處理邏輯進(jìn)行不同狀態(tài)的跳轉(zhuǎn),如下代碼
if (checkScanOnlyModeAvailable()) {
setInitialState(mStaDisabledWithScanState);
} else {
setInitialState(mStaDisabledState);
}
WifiController的初始狀態(tài)為mStaDisabledState,所以CMD_WIFI_TOGGLED消息應(yīng)該在此狀態(tài)下處理,查看其處理邏輯:
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;
代碼邏輯大致為:
先判斷當(dāng)前設(shè)備狀態(tài)是否支持打開wifi,如下方法:
public synchronized boolean isWifiToggleEnabled() {
if (!mCheckSavedStateAtBoot) {
mCheckSavedStateAtBoot = true;
if (testAndClearWifiSavedState()) return true;
}
if (mAirplaneModeOn) {
return mPersistWifiState == WIFI_ENABLED_AIRPLANE_OVERRIDE;
} else {
return mPersistWifiState != WIFI_DISABLED;
}
}
有涉及到飛行模式的相關(guān)考慮。
檢測是否兩次點擊調(diào)用開啟wifi是否時間差太短,如果太短,消息延時處理,否則的話直接跳轉(zhuǎn)到mDeviceActiveState
如果wifi當(dāng)前不支持打開,而此時“wifi scan always開關(guān)”打開,我們?nèi)匀灰蜷_wifi,進(jìn)入到mStaDisabledWithScanState狀態(tài)。
接著上面的第二個步驟,當(dāng)我們跳轉(zhuǎn)到mDeviceActiveState之后,會繼續(xù)相關(guān)邏輯處理。
WifiController狀態(tài)機(jī)此時會用到,如下:
addState(mDefaultState);
addState(mStaDisabledState, mDefaultState);
addState(mStaEnabledState, mDefaultState);
addState(mDeviceActiveState, mStaEnabledState);
addState(mStaDisabledWithScanState, mDefaultState);
addState(mEcmState, mDefaultState);
進(jìn)入到mDeviceActiveState之后會調(diào)用其enter方法,調(diào)用如下兩個方法:
mWifiStateMachinePrime.enterClientMode();
mWifiStateMachine.setHighPerfModeEnabled(false);
通過查閱代碼邏輯,可以看出:
/**
* Method to switch wifi into client mode where connections to configured networks will be
* attempted.
*/
public void enterClientMode() {
int mode = ModeStateMachine.CMD_START_CLIENT_MODE;
if (mIsSupportCucc) {
final FrameworkFacade facade = mWifiInjector.getFrameworkFacade();
int networktype = facade.getIntegerSetting(mContext,
Global.NETWORK_PREFERENCE, WIFI_DATA_TYPE);
int mobileDataStatus = facade.getIntegerSetting(mContext,
Global.MOBILE_DATA, MOBILE_DATA_ENABLE);
if (mobileDataStatus == MOBILE_DATA_ENABLE && networktype == MOBILE_DATA_TYPE) {
Log.d(TAG, "CUCC, client mode isn't allowed now, enter scan only mode");
mode = ModeStateMachine.CMD_START_SCAN_ONLY_MODE;
}
}
changeMode(mode);
}
看注釋大意為:
使wifi跳轉(zhuǎn)到client模式的一種方法,客戶端模式中,
總結(jié)
以上是生活随笔為你收集整理的Android Wifi 启动过程,AndroidP wifi启动流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android studio devic
- 下一篇: android viewpager动态加