wifisetting.java_Wifi 笔记 | 启动流程

csd:csdn_of_coder/article/details/51541094

aosp: Android O

Android网络各个模式中,Wifi应该是目前最常用的一种网络方式了;下面就简单介绍下Android中Wifi的启动流程。

当我在Setting菜单里点击打开Wifi时,调用的入口函数是WifiManager::setWifiEnabled(boolean enabled):

用户可以通过systemUi和设置里的WiFi开关打开WiFi,这时候会调用到wifi framework的相关接口,继而再继续往下启用具体的硬件完成WiFi启动流程,这里只对应用到framework层有些简单的了解,本篇也主要注重framework这一块

一、WIFI启动总体流程

WiFi打开流程还是从设置的WiFi开关开始梳理吧,不考虑打开飞行模式后打开WiFi的情况

766347d49596

总体流程

二、WIFI启动分步详解:

2.1 设置启动WiFi

设置这边说到底其实就是监控WiFi开关的变化,然后根据开关走对应的逻辑处理。

两个比较重要的类:

WifiSettings:设置中wifi主界面所对应的代码

WifiEnabler:设置中负责wifi开关打开和关闭事件处理的类

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 总结:

看到这里其实发现应用层打开和关闭WiFi就是调用了下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 注册服务

///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启动WifiService

private static final String WIFI_SERVICE_CLASS ="com.android.server.wifi.WifiService";

mSystemServiceManager.startService(WIFI_SERVICE_CLASS);

WifiService 是接口类,WifiServiceImpl 是实现类

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启动流程

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会调用WifiController来处理WIFI的启动,WifiController是一个状态机,异步处理WIF启动 过程

mWifiController.sendMessage(CMD_WIFI_TOGGLED);

mSettingsStore.handleWifiToggled(enable)设置一下SettingsProvider中存储的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,其实也顺带改了一下WifiSettingsStore的mPersistWifiState值,用来标记wifi状态。

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 状态机

mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);

mWifiStateMachine.setSupplicantRunning(true);

mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);

mWifiStateMachine.setHighPerfModeEnabled(false);

在状态处理中会发送:CMD_START_SUPPLICANT 启动协议栈的认证机制wpa_supplicant

接收到该消息进行的关键操作:

mWifiNative.enableSupplicant()

mWifiMonitor.startMonitoring(mInterfaceName, true);

切换到SupplicantStartingState状态

2.3.4 协议栈

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

}

}

完~~~

整理 | 力卉编程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值