日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

wifisetting.java_Wifi 笔记 | 启动流程

發(fā)布時(shí)間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 wifisetting.java_Wifi 笔记 | 启动流程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。