Wifi 打开 流程
App端 打开wifi操作
private WifiManager mWifiManager;
mWifiManager = (WifiManager) mContext.getSystemService(WifiManager.class);\\获取WIFI的服务
mWifiManager.setWifiEnabled(true)
让我们看一下WifiManager设置的时候是如何操作
/**
* 创建一个新的 WifiManager 实例。
* 应用程序几乎总是想要使用
* {@link #getSystemService ()} 检索
* 标准{@link #WIFI_SERVICE Context.WIFI_SERVICE}。
* @param context 应用程序上下文
* @param 服务Binder接口
* @hide - 隐藏它,因为它接受一个 IWifiManager 类型的参数,这是一个系统私有类。
*/
public WifiManager(Context context, IWifiManager service, Looper looper) {
mContext = context;
mService = service; //拿到IWifiManager的接口
mLooper = looper;
mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
}
/**
*启用或禁用Wi-Fi。
* 应用程序必须具有 {@link #CHANGE_WIFI_STATE}
*切换wifi的权限。
* @param enabled {@code true} 启用,{@code false} 禁用。
* @return {@code false} 如果请求不能被满足; {@code true} 表示 wifi 已经处于请求状态,或者正在向请求状态前进。
* @throws {@link } 如果调用者缺少所需的权限。
*/
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);//通过IWifiManager与服务进行通讯
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
WifiManager通过Binder机制与WifiServiceImpl进行通讯
WifiServerImpl
(路径:frameworks\opt\net\wifi\service\java\com\android\server\wifi\)
public class WifiServiceImpl extends IWifiManager.Stub {
/**
* 见 {@link #setWifiEnabled(boolean)}
* @param enable {@code true} 启用,{@code false} 禁用。
* @return {@code true} 如果启用/禁用操作已启动或已在队列中。
*/
@Override
public synchronized boolean setWifiEnabled(String packageName, boolean enable)
throws RemoteException {
//判断调用的app是否具有权限
if (enforceChangePermission(packageName) != MODE_ALLOWED) {
return false;
}
Slog.d(TAG, "setWifiEnabled: " + enable + " ptoken operator">+ Binder.getCallingPid()
+ ", utoken operator">+ 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 (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 = mWifiApState == WifiManager.WIFI_AP_STATE_ENABLED;
if (apEnabled && !isFromSettings) {
mLog.info("setWifiEnabled SoftAp not disabled: only Settings can enable wifi").flush();
return false;
}
/*
* 调用者可能没有 WRITE_SECURE_SETTINGS,
* 只有 CHANGE_WIFI_STATE 被强制执行
*/
long ident = Binder.clearCallingIdentity();
try {
//保存wifi状态
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;
}
}
WififController 管理wifi开关,热点开关等状态
public class WifiController extends StateMachine {
...
class StaDisabledState extends State {
...
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_WIFI_TOGGLED:
if (mSettingsStore.isWifiToggleEnabled()) {
...
transitionTo(mDeviceActiveState);//转换到了DeviceActiveState状态;
} else if (checkScanOnlyModeAvailable()) { //检测是否有被禁用位置服务
// 只有在我们不处于飞行模式时才进入扫描模式
if (mSettingsStore.isAirplaneModeOn()) {
transitionTo(mStaDisabledWithScanState);//转换到了DeviceActiveState状态
}
}
break;
}
}
...
}
...
}
class DeviceActiveState extends State {
@Override
public void enter() {
...
mWifiStateMachinePrime.enterClientMode();//调用方法
...
}
}
(路径:frameworks\opt\net\wifi\service\java\com\android\server\wifi\)
public class WifiStateMachinePrime {
....
/**
* 将 wifi 切换到客户端模式的方法,将尝试连接到配置的网络。
*/
public void enterClientMode() {
changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
}
//
private void changeMode(int newMode) {
mModeStateMachine.sendMessage(newMode);
}
private class ModeStateMachine extends StateMachine {
...
//最后会走到checkForAndHandleModeChange
private boolean checkForAndHandleModeChange(Message message) {
switch(message.what) {
case ModeStateMachine.CMD_START_CLIENT_MODE:
Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
//切换到ClientModeActiveState状态。
mModeStateMachine.transitionTo(mClientModeActiveState);
break;
...
}
return HANDLED;
}
}
}
转到ClientModeActiviteState状态
class ClientModeActiveState extends ModeActiveState {
...
@Override
public void enter() {
mManager = mWifiInjector.makeClientModeManager(mListener);
mManager.start();//跳转到ClientModeManager的start方法
}
...
}
(路径:frameworks\opt\net\wifi\service\java\com\android\server\wifi\)
public class ClientModeManager implements ActiveModeManager {
....
/**
* Start client mode.
*/
public void start() {
mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);//会跳转到IdleState(初始化时候默认是IdleState)
}
...
private class IdleState extends State {
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_START:
/**
* Update Wifi state and send the broadcast.
* @param newState new Wifi state
* @param currentState current wifi state
*/
updateWifiState(WifiManager.WIFI_STATE_ENABLING,
WifiManager.WIFI_STATE_DISABLED);
if (WifiInjector.getInstance().getAtcAospEnhancement()) {
mEnableTime = Calendar.getInstance().getTimeInMillis();
Log.d(TAG, "We will check Wi-Fi Enable time");
}
//setupInterfaceForClientMode方法startHal
mClientInterfaceName = mWifiNative.setupInterfaceForClientMode(
false /* not low priority */, mWifiNativeInterfaceCallback);
if (TextUtils.isEmpty(mClientInterfaceName)) {
Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
WifiManager.WIFI_STATE_ENABLING);
updateWifiState(WifiManager.WIFI_STATE_DISABLED,
WifiManager.WIFI_STATE_UNKNOWN);
break;
}
sendScanAvailableBroadcast(false);
mScanRequestProxy.enableScanningForHiddenNetworks(false);
mScanRequestProxy.clearScanResults();
transitionTo(mStartedState);
break;
...
}
}
}
}
总结:App端都是通过wifimanager暴露的接口通过binder机制与WifiServer进行通信。
//setupInterfaceForClientMode方法startHal,下面就是开始到hal层(后面会继续更新),可能会根据硬件芯片厂商做一些定制化的操作