wifisetting.java_Wifi 笔记 | 启动流程
csd:csdn_of_coder/article/details/51541094
aosp: Android O
Android網(wǎng)絡(luò)各個(gè)模式中,Wifi應(yīng)該是目前最常用的一種網(wǎng)絡(luò)方式了;下面就簡(jiǎn)單介紹下Android中Wifi的啟動(dòng)流程。
當(dāng)我在Setting菜單里點(diǎn)擊打開(kāi)Wifi時(shí),調(diào)用的入口函數(shù)是WifiManager::setWifiEnabled(boolean enabled):
用戶可以通過(guò)systemUi和設(shè)置里的WiFi開(kāi)關(guān)打開(kāi)WiFi,這時(shí)候會(huì)調(diào)用到wifi framework的相關(guān)接口,繼而再繼續(xù)往下啟用具體的硬件完成WiFi啟動(dòng)流程,這里只對(duì)應(yīng)用到framework層有些簡(jiǎn)單的了解,本篇也主要注重framework這一塊
一、WIFI啟動(dòng)總體流程
WiFi打開(kāi)流程還是從設(shè)置的WiFi開(kāi)關(guān)開(kāi)始梳理吧,不考慮打開(kāi)飛行模式后打開(kāi)WiFi的情況
總體流程
二、WIFI啟動(dòng)分步詳解:
2.1 設(shè)置啟動(dòng)WiFi
設(shè)置這邊說(shuō)到底其實(shí)就是監(jiān)控WiFi開(kāi)關(guān)的變化,然后根據(jù)開(kāi)關(guān)走對(duì)應(yīng)的邏輯處理。
兩個(gè)比較重要的類:
WifiSettings:設(shè)置中wifi主界面所對(duì)應(yīng)的代碼
WifiEnabler:設(shè)置中負(fù)責(zé)wifi開(kāi)關(guān)打開(kāi)和關(guān)閉事件處理的類
2.1.1 WifiSettings
//packages/apps/Settings/src/com/android/settings/wifi/WifiSettings.java
private WifiEnabler createWifiEnabler() {
final SettingsActivity activity = (SettingsActivity) getActivity();
return new WifiEnabler(activity, new SwitchBarController(activity.getSwitchBar()),
mMetricsFeatureProvider);
}
//packages/apps/Settings/src/com/android/settings/widget/SwitchBarController.java
public class SwitchBarController extends SwitchWidgetController implements
}
2.1.2 WifiEnabler
//packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java
WifiEnabler(Context context, SwitchWidgetController switchWidget,
}
//省略N多代碼
{
mWifiManager.setWifiEnabled(isChecked)) {
}
}
2.1.3 總結(jié):
看到這里其實(shí)發(fā)現(xiàn)應(yīng)用層打開(kāi)和關(guān)閉WiFi就是調(diào)用了下WifiManager的setWifiEabled(boolean)接口即可。
2.2 WiFi framework
2.2.1 WifiManager的setWifiEabled接口
//framework/base/wifi/java/android/net/wifi/WifiManager.java
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
2.2.2 WifiService的setWifiEnabled
IWifiManager mService;
public WifiManager(Context context, IWifiManager service, Looper looper) {
mContext = context;
mService = service;
mLooper = looper;
mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
}
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
2.2.3 注冊(cè)服務(wù)
///framework/base/core/java/android/app/SystemServiceRegistry.java
registerService(Context.WIFI_SERVICE, WifiManager.class,
new CachedServiceFetcher() {
@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());
}});
IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_SERVICE);
2.2.4 WifiService
SystemServer啟動(dòng)WifiService
private static final String WIFI_SERVICE_CLASS ="com.android.server.wifi.WifiService";
mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
WifiService 是接口類,WifiServiceImpl 是實(shí)現(xiàn)類
public final class WifiService extends SystemService {
private static final String TAG = "WifiService";
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);
}
2.3 Service的WiFi啟動(dòng)流程
public class WifiServiceImpl extends IWifiManager.Stub {
/**
* 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 {
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;
}
2.3.1 WifiController 中的WIFI
service會(huì)調(diào)用WifiController來(lái)處理WIFI的啟動(dòng),WifiController是一個(gè)狀態(tài)機(jī),異步處理WIF啟動(dòng) 過(guò)程
mWifiController.sendMessage(CMD_WIFI_TOGGLED);
mSettingsStore.handleWifiToggled(enable)設(shè)置一下SettingsProvider中存儲(chǔ)的WIFI_ON的值
public synchronized boolean handleWifiToggled(boolean wifiEnabled) {
// Can Wi-Fi be toggled in airplane mode ?
if (mAirplaneModeOn && !isAirplaneToggleable()) {
return false;
}
if (wifiEnabled) {
if (mAirplaneModeOn) {
persistWifiState(WIFI_ENABLED_AIRPLANE_OVERRIDE);
} else {
persistWifiState(WIFI_ENABLED);
}
} else {
// When wifi state is disabled, we do not care
// if airplane mode is on or not. The scenario of
// wifi being disabled due to airplane mode being turned on
// is handled handleAirplaneModeToggled()
persistWifiState(WIFI_DISABLED);
}
return true;
}
WifiServiceImpl在走到WifiController之前有提及修改了一下SettingsProvider,其實(shí)也順帶改了一下WifiSettingsStore的mPersistWifiState值,用來(lái)標(biāo)記wifi狀態(tài)。
persistWifiState(WIFI_ENABLED);
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;
}
}
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;
}
mReEnableDelayMillis = mFacade.getLongSetting(mContext,
Settings.Global.WIFI_REENABLE_DELAY_MS, DEFAULT_REENABLE_DELAY_MS);
2.3.2 WifiStateMachine 狀態(tài)機(jī)
mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
mWifiStateMachine.setSupplicantRunning(true);
mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
mWifiStateMachine.setHighPerfModeEnabled(false);
在狀態(tài)處理中會(huì)發(fā)送:CMD_START_SUPPLICANT 啟動(dòng)協(xié)議棧的認(rèn)證機(jī)制wpa_supplicant
接收到該消息進(jìn)行的關(guān)鍵操作:
mWifiNative.enableSupplicant()
mWifiMonitor.startMonitoring(mInterfaceName, true);
切換到SupplicantStartingState狀態(tài)
2.3.4 協(xié)議棧
public boolean enableSupplicant() {
return mWificondControl.enableSupplicant();
}
public synchronized void startMonitoring(String iface, boolean isStaIface) {
if (ensureConnectedLocked()) {
setMonitoring(iface, true);
broadcastSupplicantConnectionEvent(iface);
} else {
boolean originalMonitoring = isMonitoring(iface);
setMonitoring(iface, true);
broadcastSupplicantDisconnectionEvent(iface);
setMonitoring(iface, originalMonitoring);
Log.e(TAG, "startMonitoring(" + iface + ") failed!");
}
}
2.3.5 WifiNative中的Supplicant
private void setSuspendOptimizationsNative(int reason, boolean enabled) {
if (mVerboseLoggingEnabled) {
log("setSuspendOptimizationsNative: " + reason + " " + enabled
+ " -want " + mUserWantsSuspendOpt.get()
+ " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
+ " - " + Thread.currentThread().getStackTrace()[3].getMethodName()
+ " - " + Thread.currentThread().getStackTrace()[4].getMethodName()
+ " - " + Thread.currentThread().getStackTrace()[5].getMethodName());
}
//mWifiNative.setSuspendOptimizations(enabled);
if (enabled) {
mSuspendOptNeedsDisabled &= ~reason;
/* None of dhcp, screen or highperf need it disabled and user wants it enabled */
if (mSuspendOptNeedsDisabled == 0 && mUserWantsSuspendOpt.get()) {
if (mVerboseLoggingEnabled) {
log("setSuspendOptimizationsNative do it " + reason + " " + enabled
+ " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
+ " - " + Thread.currentThread().getStackTrace()[3].getMethodName()
+ " - " + Thread.currentThread().getStackTrace()[4].getMethodName()
+ " - " + Thread.currentThread().getStackTrace()[5].getMethodName());
}
mWifiNative.setSuspendOptimizations(true);
}
} else {
mSuspendOptNeedsDisabled |= reason;
mWifiNative.setSuspendOptimizations(false);
}
}
完~~~
整理 | 力卉編程
總結(jié)
以上是生活随笔為你收集整理的wifisetting.java_Wifi 笔记 | 启动流程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: fsw.exe是什么进程 有什么作用 f
- 下一篇: csm和uefi_关于CSM和UEFI你