赞
踩
android 11打开热点时序图如下,下面将根据时序图分析:
WifiTetherFragment是实现开关热点的Fragment,调用TetherManager::startTethering()去开启WiFi共享
/*** com.android.car.settings.wifi.WifiTetherFragment.startTethering ***/
private void startTethering() {
mTetheringManager.startTethering(ConnectivityManager.TETHERING_WIFI,
ConcurrentUtils.DIRECT_EXECUTOR,
new TetheringManager.StartTetheringCallback() {
@Override
public void onTetheringFailed(final int result) {
mTetherSwitch.setChecked(false);
mTetherSwitch.setEnabled(true);
}
});
}
TetheringManager内部通过ITetheringConnector实现具体功能,类似于WifiManager
/*** android.net.TetheringManager.startTethering ***/
public void startTethering(@NonNull final TetheringRequest request,
@NonNull final Executor executor, @NonNull final StartTetheringCallback callback) {
final String callerPkg = mContext.getOpPackageName();
Log.i(TAG, "startTethering caller:" + callerPkg);
...
getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener));
}
传入的Tethering type是ConnectivityManager.TETHERING_WIFI,直接看TetheringService
startTethering之前需要check是否支持操作热点
/*** com.android.networkstack.tethering.TetheringService.TetheringConnector.startTethering ***/
public void startTethering(TetheringRequestParcel request, String callerPkg, IIntResultListener listener) {
if (checkAndNotifyCommonError(callerPkg, request.exemptFromEntitlementCheck /* onlyAllowPrivileged */, listener)) {
return;
}
mTethering.startTethering(request, listener);
}
在enableTetheringInternal之前需要检查没有其他打开热点的请求
/*** com.android.networkstack.tethering.Tethering.startTethering ***/
void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) {
mHandler.post(() -> {
...
if (unfinishedRequest != null
&& !TetheringUtils.isTetheringRequestEquals(unfinishedRequest, request)) {
enableTetheringInternal(request.tetheringType, false /* disabled */, null);
mEntitlementMgr.stopProvisioningIfNeeded(request.tetheringType);
}
...
enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
});
}
打开对应请求的功能,这里对应的应该是TETHERING_WIFI
/*** com.android.networkstack.tethering.Tethering.enableTetheringInternal ***/
private void enableTetheringInternal(int type, boolean enable, final IIntResultListener listener) {
int result = TETHER_ERROR_NO_ERROR;
switch (type) {
case TETHERING_WIFI:
result = setWifiTethering(enable);
break;
...
}
...
}
获取WifiManager对象后操作startTetheredHotspot
/*** com.android.networkstack.tethering.Tethering.setWifiTethering ***/
private int setWifiTethering(final boolean enable) {
...
if ((enable && mgr.startTetheredHotspot(null /* use existing softap config */))
|| (!enable && mgr.stopSoftAp())) {
mWifiTetherRequested = enable;
return TETHER_ERROR_NO_ERROR;
}
...
}
/*** android.net.wifi.WifiManager.startTetheredHotspot ***/
public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
try {
return mService.startTetheredHotspot(softApConfig);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
调用内部方法startSoftApInternal
/*** com.android.server.wifi.WifiServiceImpl.startTetheredHotspot ***/
public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
...
if (!startSoftApInternal(new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
mTetheredSoftApTracker.getSoftApCapability()))) {
mTetheredSoftApTracker.setFailedWhileEnabling();
return false;
}
return true;
}
封装了状态机中的startSoftAp接口
/*** com.android.server.wifi.WifiServiceImpl.startSoftApInternal ***/
private boolean startSoftApInternal(SoftApModeConfiguration apConfig) {
...
mActiveModeWarden.startSoftAp(apConfig);
return true;
}
通过WifiController状态机,发送热点状态消息
/*** com.android.server.wifi.ActiveModeWarden.startSoftAp ***/
public void startSoftAp(SoftApModeConfiguration softApConfig) {
mWifiController.sendMessage(WifiController.CMD_SET_AP, 1, 0, softApConfig);
}
状态机之前应该是DisabledState状态,因此处理此消息流程如下
/*** com.android.server.wifi.ActiveModeWarden.WifiController.DisabledState.processMessageFiltered ***/ public boolean processMessageFiltered(Message msg) { switch (msg.what) { ... case CMD_SET_AP: // note: CMD_SET_AP is handled/dropped in ECM mode - will not start here if (msg.arg1 == 1) { startSoftApModeManager((SoftApModeConfiguration) msg.obj); transitionTo(mEnabledState); } break; ... } return HANDLED; }
/*** com.android.server.wifi.ActiveModeWarden.startSoftApModeManager ***/
private void startSoftApModeManager(@NonNull SoftApModeConfiguration softApConfig) {
...
SoftApListener listener = new SoftApListener();
ActiveModeManager manager =
mWifiInjector.makeSoftApManager(listener, callback, softApConfig);
listener.setActiveModeManager(manager);
manager.start();
manager.setRole(getRoleForSoftApIpMode(softApConfig.getTargetMode()));
mActiveModeManagers.add(manager);
}
ActiveModeManager是SoftApManager的基类,实际调用到SoftApManager.start,状态机发送SoftApStateMachine.CMD_START消息
/*** com.android.server.wifi.SoftApManager.start ***/
public void start() {
mStateMachine.sendMessage(SoftApStateMachine.CMD_START);
}
IdleState为初始状态,因此状态机在IdleState时处理此消息,处理成功之后状态机跳转到StartedState
广播ap状态变更为WIFI_AP_STATE_ENABLING
/*** com.android.server.wifi.SoftApManager.SoftApStateMachine.IdleState.processMessage ***/
case CMD_START:
SoftApConfiguration config = (SoftApConfiguration) message.obj;
...
updateApState(WifiManager.WIFI_AP_STATE_ENABLING, WifiManager.WIFI_AP_STATE_DISABLED, 0);
int result = startSoftAp();
if (result != SUCCESS)
...
transitionTo(mStartedState);
break;
最后调到WifiNative,它的状态由SoftApListener回调管理
/*** com.android.server.wifi.SoftApManager.startSoftAp ***/
private int startSoftAp() {
...
if (!mWifiNative.startSoftAp(mApInterfaceName,
localConfigBuilder.build(), mSoftApListener)) {
Log.e(TAG, "Soft AP start failed");
return ERROR_GENERIC;
}
...
return SUCCESS;
}
native之后
调用到HostapdHal.addAccessPoint
/*** com.android.server.wifi.WifiNative.startSoftAp ***/
...
if (mHostapHal.isVendorHostapHal()) {
if (!mHostapHal.addVendorAccessPoint(ifaceName, config, listener)) {
...
}
} else if (!mHostapHal.addAccessPoint(ifaceName, config, listener::onFailure)) {
...
}
...
最终调用到hal层addAccessPoint接口
/*** com.android.server.wifi.HostapdHal.addAccessPoint ***/
//Hostapd HAL interface objects
private IHostapd mIHostapd;
...
status = mIHostapd.addAccessPoint(ifaceParams, nwParamsV1_2.V1_0);
...
step15之后SoftApStateMachine状态机进入StartedState,进入enter,比较重要的是此时会设置一个默认600000ms(10min)的timeout超时机制,如果此时间段一直没有设备连接该AP,就会自动关闭AP
从WifiNative成功建立了iface之后,调用onUpChanged进行广播状态切换为WifiManager.WIFI_AP_STATE_ENABLED
/*** com.android.server.wifi.SoftApManager.SoftApStateMachine.StatedState.enter ***/ public void enter() { mIfaceIsUp = false; mIfaceIsDestroyed = false; onUpChanged(mWifiNative.isInterfaceUp(mApInterfaceName)); onUpChanged(mWifiNative.isInterfaceUp(mDataInterfaceName)); Handler handler = mStateMachine.getHandler(); mSoftApTimeoutMessage = new WakeupMessage(mContext, handler, SOFT_AP_SEND_MESSAGE_TIMEOUT_TAG, SoftApStateMachine.CMD_NO_ASSOCIATED_STATIONS_TIMEOUT); mSarManager.setSapWifiState(WifiManager.WIFI_AP_STATE_ENABLED); Log.d(TAG, "Resetting connected clients on start"); mConnectedClients.clear(); mEverReportMetricsForMaxClient = false; scheduleTimeoutMessage(); }
欢迎大家指正,一起学习共同进步~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。