当前位置:   article > 正文

【Android 11 framework学习之热点 打开】_android11 热点被动连接流程

android11 热点被动连接流程

android 11打开热点时序图如下,下面将根据时序图分析:
enable ap
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);
                }
            });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

传入的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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在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);
    });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

打开对应请求的功能,这里对应的应该是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;
        ...
    }
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

获取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;
            }
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
/*** android.net.wifi.WifiManager.startTetheredHotspot ***/

public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
    try {
        return mService.startTetheredHotspot(softApConfig);
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

调用内部方法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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

封装了状态机中的startSoftAp接口

/*** com.android.server.wifi.WifiServiceImpl.startSoftApInternal ***/

private boolean startSoftApInternal(SoftApModeConfiguration apConfig) {
    ...
    mActiveModeWarden.startSoftAp(apConfig);
    return true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

通过WifiController状态机,发送热点状态消息

/*** com.android.server.wifi.ActiveModeWarden.startSoftAp ***/

public void startSoftAp(SoftApModeConfiguration softApConfig) {
    mWifiController.sendMessage(WifiController.CMD_SET_AP, 1, 0, softApConfig);
}
  • 1
  • 2
  • 3
  • 4
  • 5

状态机之前应该是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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
/*** 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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

ActiveModeManager是SoftApManager的基类,实际调用到SoftApManager.start,状态机发送SoftApStateMachine.CMD_START消息

/*** com.android.server.wifi.SoftApManager.start ***/

public void start() {
    mStateMachine.sendMessage(SoftApStateMachine.CMD_START);
}
  • 1
  • 2
  • 3
  • 4
  • 5

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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

最后调到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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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)) {
    ...
}
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

最终调用到hal层addAccessPoint接口

/*** com.android.server.wifi.HostapdHal.addAccessPoint ***/

//Hostapd HAL interface objects
private IHostapd mIHostapd;
...
status = mIHostapd.addAccessPoint(ifaceParams, nwParamsV1_2.V1_0);
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

欢迎大家指正,一起学习共同进步~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/962256
推荐阅读
相关标签
  

闽ICP备14008679号