概述
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的情况
总体流程
二、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);
}
}
完~~~
整理 | 力卉编程
最后
以上就是清秀奇异果为你收集整理的wifisetting.java_Wifi 笔记 | 启动流程的全部内容,希望文章能够帮你解决wifisetting.java_Wifi 笔记 | 启动流程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复