赞
踩
ConnectivityManager mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
//开启
mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, true /* showProvisioningUi */,
mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));
//关闭
mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
frameworks\base\core\java\android\net\ConnectivityManager.java
public static final int TETHERING_WIFI = TetheringManager.TETHERING_WIFI; public static final int TETHERING_USB = TetheringManager.TETHERING_USB; public static final int TETHERING_BLUETOOTH = TetheringManager.TETHERING_BLUETOOTH; private final TetheringManager mTetheringManager; public void startTethering(int type, boolean showProvisioningUi, final OnStartTetheringCallback callback, Handler handler) { Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null."); final Executor executor = new Executor() { @Override public void execute(Runnable command) { if (handler == null) { command.run(); } else { handler.post(command); } } }; final StartTetheringCallback tetheringCallback = new StartTetheringCallback() { @Override public void onTetheringStarted() { callback.onTetheringStarted(); } @Override public void onTetheringFailed(final int error) { callback.onTetheringFailed(); } }; final TetheringRequest request = new TetheringRequest.Builder(type) .setShouldShowEntitlementUi(showProvisioningUi).build(); //追踪:在mTetheringManager 中 startTethering mTetheringManager.startTethering(request, executor, tetheringCallback); }
frameworks\base\packages\Tethering\common\TetheringLib\src\android\net\TetheringManager.java
@RequiresPermission(anyOf = { android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS }) 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); final IIntResultListener listener = new IIntResultListener.Stub() { @Override public void onResult(final int resultCode) { executor.execute(() -> { if (resultCode == TETHER_ERROR_NO_ERROR) { callback.onTetheringStarted(); } else { callback.onTetheringFailed(resultCode); } }); } }; //追踪: getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener)); } private void getConnector(ConnectorConsumer consumer) { final ITetheringConnector connector; synchronized (mConnectorWaitQueue) { connector = mConnector; if (connector == null) { mConnectorWaitQueue.add(consumer); return; } } try { consumer.onConnectorAvailable(connector); } catch (RemoteException e) { throw new IllegalStateException(e); } } private interface ConnectorConsumer { void onConnectorAvailable(ITetheringConnector connector) throws RemoteException; }
从上面看是 ConnectorConsumer 的回调对象调用了 startTethering 方法
查哪个应用实现了 ITetheringConnector:
frameworks\base\packages\Tethering\src\com\android\networkstack\tethering\TetheringService.java
TetheringService.TetheringConnector.startTethering
//内部接口类 private static class TetheringConnector extends ITetheringConnector.Stub { private final TetheringService mService; private final Tethering mTethering; TetheringConnector(Tethering tether, TetheringService service) { mTethering = tether; mService = service; } @Override public void tether(String iface, String callerPkg, IIntResultListener listener) { if (checkAndNotifyCommonError(callerPkg, listener)) return; try { listener.onResult(mTethering.tether(iface)); } catch (RemoteException e) { } } @Override public void startTethering(TetheringRequestParcel request, String callerPkg, IIntResultListener listener) { if (checkAndNotifyCommonError(callerPkg, request.exemptFromEntitlementCheck /* onlyAllowPrivileged */, listener)) { return; } //追踪:Tethering.startTethering mTethering.startTethering(request, listener); } @Override public void stopTethering(int type, String callerPkg, IIntResultListener listener) { if (checkAndNotifyCommonError(callerPkg, listener)) return; try { mTethering.stopTethering(type); listener.onResult(TETHER_ERROR_NO_ERROR); } catch (RemoteException e) { } } }
继续追踪Tethering 的 startTethering 方法
frameworks\base\packages\Tethering\src\com\android\networkstack\tethering\Tethering.java
void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) { mHandler.post(() -> { final TetheringRequestParcel unfinishedRequest = mActiveTetheringRequests.get( request.tetheringType); // If tethering is already enabled with a different request, // disable before re-enabling. if (unfinishedRequest != null && !TetheringUtils.isTetheringRequestEquals(unfinishedRequest, request)) { enableTetheringInternal(request.tetheringType, false /* disabled */, null); mEntitlementMgr.stopProvisioningIfNeeded(request.tetheringType); } mActiveTetheringRequests.put(request.tetheringType, request); if (request.exemptFromEntitlementCheck) { mEntitlementMgr.setExemptedDownstreamType(request.tetheringType); } else { mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType, request.showProvisioningUi); } //追踪: enableTetheringInternal(request.tetheringType, true /* enabled */, listener); }); } 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; 。。。 case TETHERING_ETHERNET: result = setEthernetTethering(enable); break; default: Log.w(TAG, "Invalid tether type."); result = TETHER_ERROR_UNKNOWN_TYPE; } // The result of Bluetooth tethering will be sent by #setBluetoothTethering. if (type != TETHERING_BLUETOOTH) { sendTetherResult(listener, result, type); } } private int setWifiTethering(final boolean enable) { final long ident = Binder.clearCallingIdentity(); try { synchronized (mPublicSync) { final WifiManager mgr = getWifiManager(); //最终还是调用了 wifiManager if (mgr == null) { mLog.e("setWifiTethering: failed to get WifiManager!"); return TETHER_ERROR_SERVICE_UNAVAIL; } //追踪: if ((enable && mgr.startTetheredHotspot(null /* use existing softap config */)) || (!enable && mgr.stopSoftAp())) { mWifiTetherRequested = enable; return TETHER_ERROR_NO_ERROR; } } } finally { Binder.restoreCallingIdentity(ident); } return TETHER_ERROR_INTERNAL_ERROR; }
frameworks\base\wifi\java\android\net\wifi\WifiManager.java
@SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.NETWORK_STACK, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK }) public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) { try { //追踪: return mService.startTetheredHotspot(softApConfig); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
继续追一下WifiMananger在里面实现的
//实现类 public class BaseWifiService extends IWifiManager.Stub { 。。。 } WifiServiceImpl.startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) //更多实现的实现子类 /** * WifiService handles remote WiFi operation requests by implementing * the IWifiManager interface. */ public class WifiServiceImpl extends BaseWifiService { private final ActiveModeWarden mActiveModeWarden; @Override public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) { // NETWORK_STACK is a signature only permission. enforceNetworkStackPermission(); mLog.info("startTetheredHotspot uid=%").c(Binder.getCallingUid()).flush(); if (!mTetheredSoftApTracker.setEnablingIfAllowed()) { mLog.err("Tethering is already active.").flush(); return false; } if (!mWifiThreadRunner.call( () -> mActiveModeWarden.canRequestMoreSoftApManagers(), false)) { // Take down LOHS if it is up. mLohsSoftApTracker.stopAll(); } if (!startSoftApInternal(new SoftApModeConfiguration( WifiManager.IFACE_IP_MODE_TETHERED, softApConfig, mTetheredSoftApTracker.getSoftApCapability()))) { mTetheredSoftApTracker.setFailedWhileEnabling(); return false; } return true; } private boolean startSoftApInternal(SoftApModeConfiguration apConfig) { int uid = Binder.getCallingUid(); boolean privileged = isSettingsOrSuw(Binder.getCallingPid(), uid); mLog.trace("startSoftApInternal uid=% mode=%") .c(uid).c(apConfig.getTargetMode()).flush(); // null wifiConfig is a meaningful input for CMD_SET_AP; it means to use the persistent // AP config. SoftApConfiguration softApConfig = apConfig.getSoftApConfiguration(); //存在 softApConfig 为 null的情况,所以不会进这里 if (softApConfig != null && (!WifiApConfigStore.validateApWifiConfiguration(softApConfig, privileged) || !validateSoftApBand(softApConfig.getBand()))) { Log.e(TAG, "Invalid SoftApConfiguration"); return false; } //追踪: mActiveModeWarden.startSoftAp(apConfig); return true; } }
值得注意的是上面的startSoftApInternal 方法中,
SoftApModeConfiguration apConfig 不为空,并且传入到后面的处理也不为空
只是SoftApConfiguration softApConfig = apConfig.getSoftApConfiguration();里面的softApConfig对象为null而已!
frameworks\opt\net\wifi\service\java\com\android\server\wifi\SoftApModeConfiguration.java
相当于一个普通的Bean类
class SoftApModeConfiguration { /** * Routing mode. Either {@link android.net.wifi.WifiManager#IFACE_IP_MODE_TETHERED} * or {@link android.net.wifi.WifiManager#IFACE_IP_MODE_LOCAL_ONLY}. */ private final int mTargetMode; private final SoftApCapability mCapability; /** * SoftApConfiguration for internal use, or null if it hasn't been generated yet. */ private final @Nullable SoftApConfiguration mSoftApConfig; SoftApModeConfiguration(int targetMode, @Nullable SoftApConfiguration config, SoftApCapability capability) { Preconditions.checkArgument( targetMode == WifiManager.IFACE_IP_MODE_TETHERED || targetMode == WifiManager.IFACE_IP_MODE_LOCAL_ONLY); mTargetMode = targetMode; mSoftApConfig = config; mCapability = capability; } public int getTargetMode() { return mTargetMode; } public SoftApConfiguration getSoftApConfiguration() { return mSoftApConfig; } public SoftApCapability getCapability() { return mCapability; } }
frameworks\opt\net\wifi\service\java\com\android\server\wifi\ActiveModeWarden.java
private final WifiController mWifiController; private final WifiInjector mWifiInjector; /** Starts SoftAp. */ public void startSoftAp(SoftApModeConfiguration softApConfig) { //追踪:CMD_SET_AP mWifiController.sendMessage(WifiController.CMD_SET_AP, 1, 0, softApConfig); } /** * WifiController is the class used to manage wifi state for various operating * modes (normal, airplane, wifi hotspot, etc.). */ private class WifiController extends StateMachine { private static final String TAG = "WifiController"; // Maximum limit to use for timeout delay if the value from overlay setting is too large. private static final int MAX_RECOVERY_TIMEOUT_DELAY_MS = 4000; private static final int BASE = Protocol.BASE_WIFI_CONTROLLER; static final int CMD_EMERGENCY_MODE_CHANGED = BASE + 1; static final int CMD_SCAN_ALWAYS_MODE_CHANGED = BASE + 7; static final int CMD_WIFI_TOGGLED = BASE + 8; static final int CMD_AIRPLANE_TOGGLED = BASE + 9; static final int CMD_SET_AP = BASE + 10; ... static final int CMD_RECOVERY_DISABLE_WIFI = BASE + 19; static final int CMD_STA_STOPPED = BASE + 20; static final int CMD_DEFERRED_RECOVERY_RESTART_WIFI = BASE + 22; static final int CMD_AP_START_FAILURE = BASE + 23; static final int CMD_UPDATE_AP_CAPABILITY = BASE + 24; static final int CMD_UPDATE_AP_CONFIG = BASE + 25; class EnabledState extends BaseState { @Override public boolean processMessageFiltered(Message msg) { switch (msg.what) { 。。。 //追踪:CMD_SET_AP 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); } else { stopSoftApModeManagers(msg.arg2); } break; case CMD_AP_STOPPED: case CMD_AP_START_FAILURE: 。。。 default: return NOT_HANDLED; } return HANDLED; } } } private void startSoftApModeManager(@NonNull SoftApModeConfiguration softApConfig) { Log.d(TAG, "Starting SoftApModeManager config = " + softApConfig.getSoftApConfiguration()); Preconditions.checkState(softApConfig.getTargetMode() == IFACE_IP_MODE_LOCAL_ONLY || softApConfig.getTargetMode() == IFACE_IP_MODE_TETHERED); WifiManager.SoftApCallback callback = softApConfig.getTargetMode() == IFACE_IP_MODE_LOCAL_ONLY ? mLohsCallback : mSoftApCallback; SoftApListener listener = new SoftApListener(); ActiveModeManager manager = mWifiInjector.makeSoftApManager(listener, callback, softApConfig); listener.setActiveModeManager(manager); manager.start(); manager.setRole(getRoleForSoftApIpMode(softApConfig.getTargetMode())); mActiveModeManagers.add(manager); }
frameworks\opt\net\wifi\service\java\com\android\server\wifi\ActiveModeManager.java
public interface ActiveModeManager { /** * Listener for ActiveModeManager state changes. */ interface Listener { void onStarted(); void onStopped(); void onStartFailure(); } void start(); void stop(); boolean isStopping(); }
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiInjector.java
public SoftApManager makeSoftApManager(@NonNull ActiveModeManager.Listener listener,
@NonNull WifiManager.SoftApCallback callback,
@NonNull SoftApModeConfiguration config) {
return new SoftApManager(mContext, mWifiHandlerThread.getLooper(),
mFrameworkFacade, mWifiNative, mCountryCode.getCountryCode(), listener, callback,
mWifiApConfigStore, config, mWifiMetrics, mSarManager, mWifiDiagnostics);
}
frameworks\opt\net\wifi\service\java\com\android\server\wifi\SoftApManager.java
SoftApManager 实现了 ActiveModeManager接口,
SoftApManager.startSoftAp()
里面包含了 SoftApStateMachine ,就是所谓的状态机对象
上面ActiveModeManager.start(); 就是调用到 SoftApManager.start();最终调到 startSoftAp方法
/** * Manage WiFi in AP mode. * The internal state machine runs under the ClientModeImpl handler thread context. */ public class SoftApManager implements ActiveModeManager { private static final String TAG = "SoftApManager"; private final SoftApStateMachine mStateMachine; private final WifiApConfigStore mWifiApConfigStore; /** * Start soft AP, as configured in the constructor. */ @Override public void start() { //追踪:CMD_START mStateMachine.sendMessage(SoftApStateMachine.CMD_START); } private class SoftApStateMachine extends StateMachine { // Commands for the state machine. public static final int CMD_START = 0; public static final int CMD_STOP = 1; 。。。 public static final int CMD_UPDATE_CONFIG = 11; SoftApStateMachine(Looper looper) { super(TAG, looper); addState(mIdleState); addState(mStartedState); setInitialState(mIdleState); start(); } private class IdleState extends State { @Override public void enter() { mApInterfaceName = null; mIfaceIsUp = false; mIfaceIsDestroyed = false; } private class SoftApStateMachine extends StateMachine { // Commands for the state machine. public static final int CMD_START = 0; public static final int CMD_STOP = 1; 。。。 public static final int CMD_UPDATE_CONFIG = 11; SoftApStateMachine(Looper looper) { super(TAG, looper); addState(mIdleState); addState(mStartedState); setInitialState(mIdleState); start(); } private class IdleState extends State { @Override public void enter() { mApInterfaceName = null; mIfaceIsUp = false; mIfaceIsDestroyed = false; } @Override public boolean processMessage(Message message) { switch (message.what) { case CMD_STOP: mStateMachine.quitNow(); break; //追踪:CMD_START case CMD_START: mApInterfaceName = mWifiNative.setupInterfaceForSoftApMode( mWifiNativeInterfaceCallback); if (TextUtils.isEmpty(mApInterfaceName)) { Log.e(TAG, "setup failure when creating ap interface."); updateApState(WifiManager.WIFI_AP_STATE_FAILED, WifiManager.WIFI_AP_STATE_DISABLED, WifiManager.SAP_START_FAILURE_GENERAL); mWifiMetrics.incrementSoftApStartResult( false, WifiManager.SAP_START_FAILURE_GENERAL); mModeListener.onStartFailure(); break; } mSoftApNotifier.dismissSoftApShutDownTimeoutExpiredNotification(); updateApState(WifiManager.WIFI_AP_STATE_ENABLING, WifiManager.WIFI_AP_STATE_DISABLED, 0); //追踪:重点关注! int result = startSoftAp(); //关键流程 if (result != SUCCESS) { int failureReason = WifiManager.SAP_START_FAILURE_GENERAL; if (result == ERROR_NO_CHANNEL) { failureReason = WifiManager.SAP_START_FAILURE_NO_CHANNEL; } else if (result == ERROR_UNSUPPORTED_CONFIGURATION) { failureReason = WifiManager .SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION; } updateApState(WifiManager.WIFI_AP_STATE_FAILED, WifiManager.WIFI_AP_STATE_ENABLING, failureReason); stopSoftAp(); mWifiMetrics.incrementSoftApStartResult(false, failureReason); mModeListener.onStartFailure(); break; } transitionTo(mStartedState); break; 。。。 default: // Ignore all other commands. break; } return HANDLED; } } //整个系统热点开启最重要的地方,通过这里日志能知道是否开启热点成功 /** * Start a soft AP instance as configured. * * @return integer result code */ private int startSoftAp() { SoftApConfiguration config = mApConfig.getSoftApConfiguration(); //(1)判断配置对话和名称是否为null if (config == null || config.getSsid() == null) { Log.e(TAG, "Unable to start soft AP without valid configuration"); return ERROR_GENERIC; } Log.d(TAG, "band " + config.getBand() + " iface " + mApInterfaceName + " country " + mCountryCode); //(2)判断是否能设置MAC地址 int result = setMacAddress(); if (result != SUCCESS) { return result; } //(3)判断是否能设置CountryCode,5G热点,band =2 的情况才要设置 result = setCountryCode(); if (result != SUCCESS) { return result; } //(4)重新创建一个热点配置对象,这个对象的数据才是传递给底层的! // Make a copy of configuration for updating AP band and channel. SoftApConfiguration.Builder localConfigBuilder = new SoftApConfiguration.Builder(config); boolean acsEnabled = mCurrentSoftApCapability.areFeaturesSupported( SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD); //(5)重点来了!这里是有更新配置的逻辑 result = ApConfigUtil.updateApChannelConfig( mWifiNative, mContext.getResources(), mCountryCode, localConfigBuilder, config, acsEnabled); if (result != SUCCESS) { Log.e(TAG, "Failed to update AP band and channel"); return result; } if (config.isHiddenSsid()) { Log.d(TAG, "SoftAP is a hidden network"); } //后面的都是一些基本检测和动作 //(6)检测热点配置是否支持 if (!ApConfigUtil.checkSupportAllConfiguration(config, mCurrentSoftApCapability)) { Log.d(TAG, "Unsupported Configuration detect! config = " + config); return ERROR_UNSUPPORTED_CONFIGURATION; } //(7)启动热点 if (!mWifiNative.startSoftAp(mApInterfaceName, localConfigBuilder.build(), mSoftApListener)) { Log.e(TAG, "Soft AP start failed"); return ERROR_GENERIC; } mWifiDiagnostics.startLogging(mApInterfaceName); mStartTimestamp = FORMATTER.format(new Date(System.currentTimeMillis())); //(8)热点启动成功的标志! Log.d(TAG, "Soft AP is started "); return SUCCESS; } }
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiNative.java
private final HostapdHal mHostapdHal; public boolean startSoftAp( @NonNull String ifaceName, SoftApConfiguration config, SoftApListener listener) { if (!mWifiCondManager.registerApCallback(ifaceName, Runnable::run, listener)) { Log.e(TAG, "Failed to register ap listener"); return false; } if (!mHostapdHal.addAccessPoint(ifaceName, config, listener::onFailure)) { Log.e(TAG, "Failed to add acccess point"); mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHostapd(); return false; } return true; }
frameworks\opt\net\wifi\service\java\com\android\server\wifi\HostapdHal.java
public boolean addAccessPoint(@NonNull String ifaceName, @NonNull SoftApConfiguration config, @NonNull Runnable onFailureListener) { synchronized (mLock) { int band; boolean enableAcs = ApConfigUtil.isAcsSupported(mContext) && config.getChannel() == 0 && !mForceApChannel; if (enableAcs) { ifaceParams.channelParams.enableAcs = true; ifaceParams.channelParams.acsShouldExcludeDfs = !mContext.getResources() .getBoolean(R.bool.config_wifiSoftapAcsIncludeDfs); } //可以打印下channel 和 band 的值,查看传递给底层的具体数据 ifaceParams.channelParams.channel = mForceApChannel ? mForcedApChannel : config.getChannel(); band = mForceApChannel ? mForcedApBand : config.getBand(); //添加传入到底层的数据: Log.i(TAG, "band = " + band + ", channel = " + ifaceParams.channelParams.channel); android.hardware.wifi.hostapd.V1_2.IHostapd.NetworkParams nwParamsV1_2 = prepareNetworkParams(config); if (nwParamsV1_2 == null) return false; if (!checkHostapdAndLogFailure(methodStr)) return false; try { HostapdStatus status; if (!isV1_1() && !isV1_2()) { ifaceParams.channelParams.band = getHalBand(band); status = mIHostapd.addAccessPoint(ifaceParams, nwParamsV1_2.V1_0); if (!checkStatusAndLogFailure(status, methodStr)) { return false; } } else { android.hardware.wifi.hostapd.V1_1.IHostapd.IfaceParams ifaceParams1_1 = new android.hardware.wifi.hostapd.V1_1.IHostapd.IfaceParams(); ifaceParams1_1.V1_0 = ifaceParams; if (!isV1_2()) { ifaceParams.channelParams.band = getHalBand(band); if (ifaceParams.channelParams.enableAcs) { if ((band & SoftApConfiguration.BAND_2GHZ) != 0) { ifaceParams1_1.channelParams.acsChannelRanges.addAll( toAcsChannelRanges(mContext.getResources().getString( R.string.config_wifiSoftap2gChannelList))); } if ((band & SoftApConfiguration.BAND_5GHZ) != 0) { ifaceParams1_1.channelParams.acsChannelRanges.addAll( toAcsChannelRanges(mContext.getResources().getString( R.string.config_wifiSoftap5gChannelList))); } } android.hardware.wifi.hostapd.V1_1.IHostapd iHostapdV1_1 = getHostapdMockableV1_1(); if (iHostapdV1_1 == null) return false; status = iHostapdV1_1.addAccessPoint_1_1(ifaceParams1_1, nwParamsV1_2.V1_0); if (!checkStatusAndLogFailure(status, methodStr)) { return false; } ifaceParams.channelParams.channel = mForceApChannel ? mForcedApChannel : config.getChannel(); band = mForceApChannel ? mForcedApBand : config.getBand(); android.hardware.wifi.hostapd.V1_2.IHostapd.NetworkParams nwParamsV1_2 = prepareNetworkParams(config); } else { android.hardware.wifi.hostapd.V1_2.HostapdStatus status12; android.hardware.wifi.hostapd.V1_2.IHostapd.IfaceParams ifaceParams1_2 = new android.hardware.wifi.hostapd.V1_2.IHostapd.IfaceParams(); ifaceParams1_2.V1_1 = ifaceParams1_1; ifaceParams1_2.hwModeParams.enable80211AX = mContext.getResources().getBoolean( R.bool.config_wifiSoftapIeee80211axSupported); ifaceParams1_2.hwModeParams.enable6GhzBand = mContext.getResources().getBoolean( R.bool.config_wifiSoftap6ghzSupported); ifaceParams1_2.hwModeParams.enableHeSingleUserBeamformer = mContext.getResources().getBoolean( R.bool.config_wifiSoftapHeSuBeamformerSupported); ifaceParams1_2.hwModeParams.enableHeSingleUserBeamformee = mContext.getResources().getBoolean( R.bool.config_wifiSoftapHeSuBeamformeeSupported); ifaceParams1_2.hwModeParams.enableHeMultiUserBeamformer = mContext.getResources().getBoolean( R.bool.config_wifiSoftapHeMuBeamformerSupported); ifaceParams1_2.hwModeParams.enableHeTargetWakeTime = mContext.getResources().getBoolean( R.bool.config_wifiSoftapHeTwtSupported); ifaceParams1_2.channelParams.bandMask = getHalBandMask(band); // Prepare freq ranges/lists if needed if (ifaceParams.channelParams.enableAcs && isSendFreqRangesNeeded(band)) { if ((band & SoftApConfiguration.BAND_2GHZ) != 0) { ifaceParams1_2.channelParams.acsChannelFreqRangesMhz.addAll( toAcsFreqRanges(SoftApConfiguration.BAND_2GHZ)); } if ((band & SoftApConfiguration.BAND_5GHZ) != 0) { ifaceParams1_2.channelParams.acsChannelFreqRangesMhz.addAll( toAcsFreqRanges(SoftApConfiguration.BAND_5GHZ)); } if ((band & SoftApConfiguration.BAND_6GHZ) != 0) { ifaceParams1_2.channelParams.acsChannelFreqRangesMhz.addAll( toAcsFreqRanges(SoftApConfiguration.BAND_6GHZ)); } } android.hardware.wifi.hostapd.V1_2.IHostapd iHostapdV1_2 = getHostapdMockableV1_2(); if (iHostapdV1_2 == null) return false; status12 = iHostapdV1_2.addAccessPoint_1_2(ifaceParams1_2, nwParamsV1_2); if (!checkStatusAndLogFailure12(status12, methodStr)) { return false; } } } mSoftApFailureListeners.put(ifaceName, onFailureListener); return true; } catch (IllegalArgumentException e) { Log.e(TAG, "Unrecognized apBand: " + band); return false; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } }
(1)ConnectivityManager.startTethering (2)TetheringManager.startTethering(request, executor, tetheringCallback) (3)TetheringService.TetheringConnector.startTethering (4)Tethering.startTethering(request, listener); //方法名变化,使用null 对象开启热点 (5)WifiManager.startTetheredHotspot(null /* use existing softap config */) (6)WifiServiceImpl.startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) //方法名再变化 (7)ActiveModeWarden.startSoftAp(apModeConfig); (8)ActiveModeManager.start(); ActiveModeManager manager = mWifiInjector.makeSoftApManager(listener, callback, softApConfig); listener.setActiveModeManager(manager); manager.start(); ActiveModeManager是接口类,会调用到SoftApManager.start() (9)SoftApManager.startSoftAp() (10)WifiNative.startSoftAp(mApInterfaceName, localConfigBuilder.build(), mSoftApListener) (11)HostapdHal.addAccessPoint(ifaceName, config, listener::onFailure) (12)根据硬件版本调用不同的接口实现:addAccessPoint_X_X
热点的配置在SoftApManager.startSoftAp() 会有一定的修改,
比如channel ==0 的情况是会在ApConfigUtil.java中,对应的band范围内随机生成一个channel值。
frameworks\opt\net\wifi\service\java\com\android\server\wifi\util\ApConfigUtil.java
所以热点配置有变化,需要分析的生活,可以在SoftApManager 和相关文件中多添加日志即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。