Android M WiFiManager函数调用追踪

来源:互联网 发布:unity3d项目实战教程 编辑:程序博客网 时间:2024/06/05 15:04
源代码
1. WifiManager.java:frameworks\base\wifi\java\android\net\wifi\
2. IWifiManager.aidl:frameworks\base\wifi\java\android\net\wifi\
3. WifiServiceImpl.java:frameworks\opt\net\wifi\service\java\com\android\server\wifi
4. WifiController.java:frameworks\opt\net\wifi\service\java\com\android\server\wifi
5. WiFiStateMachine.java:frameworks\opt\net\wifi\service\java\com\android\server\wifi
6. WifiNative.java:frameworks\opt\net\wifi\service\java\com\android\server\wifi
7. com_android_server_wifi_WifiNativie.cpp:frameworks\opt\net\wifi\service\jni

通常我们去打开关闭wifi,连接断开AP,获取wifi状态,都是通过WiFiManager的接口,使用WiFiManager简单,通过如下code调用:
WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
wifiManager.xxxxx();

然后通过wifiManager对象就可以调用相关接口了。已打开Wifi为例,追踪wifi的调用流程。先看WifiManager.java中的代码:
/**
* Enable or disable Wi-Fi.
* @param enabled {@code true} to enable, {@code false} to disable.
* @return {@code true} if the operation succeeds (or if the existing state
* is the same as the requested state).
*/
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(enabled);
} catch (RemoteException e) {
return false;
}
}

接口setWiFiEnabled为打开关闭wifi的公开函数。参数布尔值enabled若为true,则表示打开,否则为关闭。我们可以看出其实调用的mService对象的setWifiEnabled(enabled)函数,mService是什么呢,看定义:
IWifiManager mService;
public WifiManager(Context context, IWifiManager service) {
mContext = context;
mService = service;
init();
}

mService是IWiFiManager类型,IWiFiManger是定义在IWifiManager.aidl中的,aidl表示为android interface definition language,通过binder机制跨进程访问。我们只需要看谁实现了IWiFiManager的接口就知道mService调用到哪了。看WifiServiceImpl的定义:
public final class WifiServiceImpl extends IWifiManager.Stub
可以知道是WifiServiceImpl实现了setWiFiEnabled(),看code:

/**
* 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.
*/
public synchronized boolean setWifiEnabled(boolean enable) {
enforceChangePermission();
Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid());
if (DBG) {
Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
}

/*
* 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);
}

mWifiController.sendMessage(CMD_WIFI_TOGGLED);
return true;
}

在WifiServiceImpl中,会向mWifiController对象发送CMD_WIFI_TOGGLED消息,WifiController继承了StateMachine的状态机类,看下WifiController中对这个消息的处理:

class StaEnabledState extends State {
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_WIFI_TOGGLED:
if (! mSettingsStore.isWifiToggleEnabled()) {
if (mSettingsStore.isScanAlwaysAvailable()) {
transitionTo(mStaDisabledWithScanState);
} else {
transitionTo(mApStaDisabledState);
}
}
break;
}
}
}

class StaDisabledWithScanState extends State {
@Override
public void enter() {
mWifiStateMachine.setSupplicantRunning(true);
mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE);
mWifiStateMachine.setDriverStart(true);
// Supplicant can't restart right away, so not the time we switched off
mDisabledTimestamp = SystemClock.elapsedRealtime();
mDeferredEnableSerialNumber++;
mHaveDeferredEnable = false;
mWifiStateMachine.clearANQPCache();
}
}
可以看到刚开始由StaEnabledState处理CMD_WIFI_TOGGLED消息,然后把状态转到StaDisabledWithScanState,进入该状态的enter()函数。可以看到,调用了WifiStateMachine类的函数。WiFiStateMahcine也是继承自StateMachine的管理wifi的状态机。我们选择setDriverStart()去跟踪,code如下:

public void setDriverStart(boolean enable) {
if (enable) {
sendMessage(CMD_START_DRIVER);
} else {
sendMessage(CMD_STOP_DRIVER);
}
}

class DriverStoppedState extends State {
@Override
public boolean processMessage(Message message) {
logStateAndMessage(message, getClass().getSimpleName());
switch (message.what) {
case CMD_START_DRIVER:
mWakeLock.acquire();
mWifiNative.startDriver();
mWakeLock.release();
transitionTo(mDriverStartingState);
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
}
看到了本地的setDriverStart()发送了一个CMD_START_DRIVER消息到状态机,由DriverStoppedState处理,调用Wifinative的startDirver()。继续看WifiNative.java的code:

public boolean startDriver() {
return doBooleanCommand("DRIVER START");
}
private boolean doBooleanCommand(String command) {
if (DBG) Log.d(mTAG, "doBoolean: " + command);
synchronized (mLock) {
int cmdId = getNewCmdIdLocked();
String toLog = Integer.toString(cmdId) + ":" + mInterfacePrefix + command;
boolean result = doBooleanCommandNative(mInterfacePrefix + command);
localLog(toLog + " -> " + result);
if (DBG) Log.d(mTAG, command + ": returned " + result);
return result;
}
}

private native boolean doBooleanCommandNative(String command);

我们可以看到startDriver最终调用到了一个JNI函数doBooleanCommandNative(),其实现是在com_android_server_wifi_WifiNativie.cpp中,code如下:
static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) {
return doBooleanCommand(env, javaCommand);
}
下面命令是到更底层HAL层,然后发命令给相应的硬件。关于WifiManager函数的追踪就到这里。
0 0
原创粉丝点击