【Android 11 framework学习之热点 打开】

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

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();
}

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

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值