wifi断开连接时序图如下,直接从framework api开始分析:
WifiManager最终调用到WifiServiceImpl中的disconnect
/*** android.net.wifi.WifiManager.disconnect ***/
public boolean disconnect() {
try {
return mService.disconnect(mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowSystemServer();
}
}
disconnect是disconnect2的一个封装,实际调用到disconnect2
/*** com.android.server.wifi.WifiServiceImpl.disconnect2 ***/
public boolean disconnect2(int staId, String packageName) {
...
if (staId == STA_PRIMARY) {
mClientModeImpl.disconnectCommand();
} ...
}
ClientModeImpl状态机中发送了CMD_DISCONNECT的消息
/*** com.android.server.wifi.ClientModeImpl.disconnectCommand ***/
public void disconnectCommand() {
sendMessage(CMD_DISCONNECT);
}
连接之后状态机为ConnectedState,接下来处理此消息,由于ConnectedState对消息CMD_DISCONNECT没有处理,将交给其父状态L2ConnectedState处理此消息
在L2ConnectedState中,直接调用了WifiNative.disconnect方法断开当前连接的热点,然后将状态机切换到DisconnectingState状态
/*** com.android.server.wifi.ClientModeImpl.L2ConnectedState.processMessage ***/
public boolean processMessage(Message message) {
...
switch (message.what) {
case CDM_DISCONNECT:
...
mWifiNative.disconnect(mInterfaceName);
transitionTo(mDisconnectingState);
break;
...
}
}
可以看到WifiNative中直接调用了 SupplicantStaIfaceHal.disconnect
/*** com.android.server.wifi.WifiNative.disconnect ***/
public boolean disconnect(@NonNull String ifaceName) {
return mSupplicantStaIfaceHal.disconnect(ifaceName);
}
通过HIDL调用了HAL层中的disconnect方法
/*** com.android.server.wifi.SupplicantStaIfaceHal.disconnect ***/
public boolean disconnect(@NonNull String ifaceName) {
...
ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr);
...
SupplicantStatus status = iface.disconnect();
...
}
上报断开状态
由于在开启wifi时,向ISupplicantStaIface注册了回调类SupplicantStaIfaceHalCallback其父类为SupplicantStaIfaceCallbackImpl,再看SupplicantStaIfaceCallbackImpl的回调方法onDisconnect
/*** com.android.server.wifi.SupplicantStaIfaceCallbackImpl.onDisconnected ***/
public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
synchronized (mLock) {
...
mWifiMonitor.broadcastNetworkDisconnectionEvent(
mIfaceName, locallyGenerated ? 1 : 0, reasonCode,
NativeUtil.macAddressFromByteArray(bssid));
}
}
这里其实是给ClientModeImpl发送消息(Handler机制),由于回调是跨进程的,所以会排在当前消息后面。
/*** com.android.server.wifi.WifiMonitor.broadcastNetworkDisconnectionEvent ***/
public void broadcastNetworkDisconnectionEvent(String iface, int local, int reason,
String bssid) {
sendMessage(iface, NETWORK_DISCONNECTION_EVENT, local, reason, bssid);
}
上面step4状态机切换到了DisconnectingState,那么 broadcastNetworkDisconnectionEvent 方法发送的NETWORK_DISCONNECTION_EVENT是交给DisconnectingState状态处理了。由于DisconnectingState状态没有处理,会交由其父状态ConnectModeState处理
调用handleNetworkDisconnect之后,状态机切换到DisconnectedState状态
/*** com.android.server.wifi.ClientModeImpl.ConnectModeState.processMessage ***/
public boolean processMessage(Message message) {
...
switch (message.what) {
...
case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
if (mVerboseLoggingEnabled) log("ConnectModeState: Network connection lost ");
clearNetworkCachedDataIfNeeded(getTargetWifiConfiguration(), message.arg2);
handleNetworkDisconnect();
transitionTo(mDisconnectedState);
break;
...
}
...
}
这里对外发送了wifi状态变化的广播,并且状态为DetailedState.DISCONNECTED,这个广播发送出去后表示wifi完全断开热点成功
/*** com.android.server.wifi.ClientModeImpl.sendNetworkChangeBroadcast ***/
private void handleNetworkDisconnect() {
...
sendNetworkChangeBroadcast(DetailedState.DISCONNECTED);
...
}
参考:
https://blog.youkuaiyun.com/qq_39036223/article/details/125166836