android wifi热点setting

目录

一、wifi原生setting的入口在WifiTetherSettings.java

二、改热点Setting的时候可以直接只编译Settings.apk,并且替换,

三、wifi热点貌似官方支持黑名单 和 支持设置热点支持的最大client数

四、热点的双频合一

1、那设置频段为5G的时候,也就是2的时候,什么时候系统会被改成3(双频)的呢,


wifi模块的重要的类:

【安卓Framework学习】Wifi框架学习之核心类_leeeeesss的博客-CSDN博客_android wifi框架

热点开发的官方文档:

https://source.android.google.cn/docs/core/connect/wifi-softap

https://developer.android.google.cn/reference/android/net/ConnectivityManager

https://developer.android.google.cn/guide/topics/connectivity/wifi-permissions

重要:

Wi-Fi HAL  |  Android 开源项目  |  Android Open Source Project

一、wifi原生setting的入口在WifiTetherSettings.java

packages/apps/Settings/src/com/android/settings/wifi/tether/WifiTetherSettings.java

  • WifiTetherSettings层

开启热点和关闭热点的最后是使用ConnectivityManager的 startTethering 和 stopTethering

packages/apps/Settings/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java

    void stopTether() {
        mSwitchBar.setEnabled(false);
        mConnectivityManager.stopTethering(TETHERING_WIFI);
    }

    void startTether() {
        mSwitchBar.setEnabled(false);
        mConnectivityManager.startTethering(TETHERING_WIFI, true /* showProvisioningUi */,
                mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));
    }

  • ConnectivityManager层

frameworks/base/core/java/android/net/ConnectivityManager.java

    public void startTethering(int type, boolean showProvisioningUi,
            final OnStartTetheringCallback callback, Handler handler) {

        mTetheringManager.startTethering(request, executor, tetheringCallback);
    }

    public void stopTethering(int type) {
        mTetheringManager.stopTethering(type);
    }

  • TetheringManager层

frameworks/base/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java

调用到Tethering

    public void startTethering(@NonNull final TetheringRequest request,
            @NonNull final Executor executor, @NonNull final StartTetheringCallback callback) {
        getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener));
    }

    public void stopTethering(@TetheringType final int type) {

        getConnector(c -> c.stopTethering(type, callerPkg, new IIntResultListener.Stub() {
            @Override
            public void onResult(int resultCode) {
            }
        }));
    }

  • Tethering层

frameworks/base/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java

最后startTethering调用到最后是WifiManager.startTetheredHotspot,

stopTethering 调用到最后是WifiManager.stopSoftAp

    void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) {
        mHandler.post(() -> {
            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_USB:
                result = setUsbTethering(enable);
                break;
            case TETHERING_BLUETOOTH:
                setBluetoothTethering(enable, listener);
                break;
            default:
                Log.w(TAG, "Invalid tether type.");
                result = TETHER_ERROR_UNKNOWN_TYPE;
        }

    }

    private int setWifiTethering(final boolean enable) {
                final WifiManager mgr = getWifiManager();
                if ((enable && mgr.startTetheredHotspot(null /* use existing softap config */))
                        || (!enable && mgr.stopSoftAp())) {
                    mWifiTetherRequested = enable;
                    return TETHER_ERROR_NO_ERROR;
                }
    }

二、改热点Setting的时候可以直接只编译Settings.apk,并且替换,

可以查看Android.bp文件

./system_ext/priv-app/Settings/Settings.apk

三、wifi热点貌似官方支持黑名单 和 支持设置热点支持的最大client数

通过 Wi-Fi 热点(软 AP)支持网络共享  |  Android 开源项目  |  Android Open Source Project

在android11热点Setting的WifiTetherSoftApManager.java, 有注册SoftapCallback, 可以重写一下onCapabilityChanged, 这样就可以获取到系统支持的最大的client数量,最后日志显示,

支持的client数量为16

12-27 11:33:33.251  2884  2884 I wqy-WifiTetherPrfeCtl: onStart
12-27 11:33:33.251  2884  2884 I wqy-WifiTetherPrfeCtl: onStart, registerSoftApCallback
12-27 11:33:33.251  2884  2884 I wqy-WifiTethSoApMgr: registerSoftApCallback
12-27 11:33:33.333  2884  2884 I wqy-WifiTethSoApMgr: onStateChanged
12-27 11:33:33.333  2884  2884 I wqy-WifiTethSoApMgr: onConnectedClientsChanged
12-27 11:33:33.333  2884  2884 I wqy-WifiTethSoApMgr: onCapabilityChanged, softApCapability = SupportedFeatures=15MaximumSupportedClientNumber=16
12-27 11:33:33.334  2884  2884 I wqy-WifiTethSoApMgr: onCapabilityChanged, maxClient = 16

packages/apps/Settings/src/com/android/settings/wifi/tether/WifiTetherSoftApManager.java

    public void registerSoftApCallback() {
        Log.i("wqy-WifiTethSoApMgr", "registerSoftApCallback");
        mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
    }

    private WifiManager.SoftApCallback mSoftApCallback = new WifiManager.SoftApCallback() {
        @Override
        public void onStateChanged(int state, int failureReason) {
            Log.i("wqy-WifiTethSoApMgr", "onStateChanged");
            mWifiTetherSoftApCallback.onStateChanged(state, failureReason);
        }

        @Override
        public void onConnectedClientsChanged(List clients) {
            Log.i("wqy-WifiTethSoApMgr", "onConnectedClientsChanged");
            mWifiTetherSoftApCallback.onConnectedClientsChanged(clients);
        }

        @Override
        public void onCapabilityChanged(@NonNull SoftApCapability softApCapability) {
            Log.i("wqy-WifiTethSoApMgr", "onCapabilityChanged, softApCapability = " + softApCapability);
            int maxClient = softApCapability.getMaxSupportedClients();
            Log.i("wqy-WifiTethSoApMgr", "onCapabilityChanged, maxClient = " + maxClient);
            // Do nothing: can be updated to add SoftApCapability details (e.g. meximum supported
            // client number) to the UI.
        }
    };

设置最大client数的地方是:

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

        public void updateSoftApCapability(int subId) {
            Log.i(TAG, "wqy updateSoftApCapability");
            synchronized (mLock) {
                CarrierConfigManager carrierConfigManager =
                        (CarrierConfigManager) mContext.getSystemService(
                        Context.CARRIER_CONFIG_SERVICE);
                int carrierMaxClient = carrierConfig.getInt(
                        CarrierConfigManager.Wifi.KEY_HOTSPOT_MAX_CLIENT_COUNT);
                int finalSupportedClientNumber = mContext.getResources().getInteger(
                        R.integer.config_wifiHardwareSoftapMaxClientCount);
                Log.i(TAG, "wqy updateSoftApCapability, config_wifiHardwareSoftapMaxClientCount = " + finalSupportedClientNumber);
                if (carrierMaxClient > 0) {
                    finalSupportedClientNumber = Math.min(finalSupportedClientNumber,
                            carrierMaxClient);
                }

                Log.i(TAG, "wqy updateSoftApCapability, carrierMaxClient = " + carrierMaxClient);
                mTetheredSoftApCapability.setMaxSupportedClients(
                        finalSupportedClientNumber);
            }
            onCapabilityChanged(mTetheredSoftApCapability);
        }

config_wifiHardwareSoftapMaxClientCount 找到的有两个地方:

frameworks/opt/net/wifi/service/res/values/config.xml (根据上面打印,应该这个,因为打印出来的是16)

16

vendor/qcom/proprietary/commonsys-intf/resource-overlay/common/Wifi/res/values/config.xml (这个暂时不知道有啥用)

32

四、热点的双频合一

工作中遇到别人提的一个bug,android里应用层设置5G Hz频段 2,设置成功后返回的频段是3,

一开始以为系统默认给开了6G,经过打日志,发现设置5G 频段的时候,它会默认检查config配置里有有没有2.4G,没有的话,会默认加上2.4G的频段, 所有设置5G 为2的时候,会默认 2 | 1 = 3,

达标双频合一,这样可以用户连接网络较弱时会自动切换到另一个Wi-Fi频段,这就极大程度保证信号的持续稳定连接,避免了手动切换信号的麻烦。

public static final int BAND_2GHZ = 1;
public static final int BAND_5GHZ = 2;
public static final int BAND_6GHZ = 4;
public static final int BAND_ANY = 7;

「技巧」关于Wi-Fi双频合一,你真的知道么?|频段|5G_新浪新闻

1、那设置频段为5G的时候,也就是2的时候,什么时候系统会被改成3(双频)的呢,

一种可能是设置的时候被修改,一种可能是重启热点的时候被修改

发现同样的链接:Android11 热点Band值为3_峥嵘life的博客-CSDN博客

经过验证:

是在设置热点配置的时候被修改的

在原生Settings里做验证:

我这儿默认是2.4G,所以先获取一下配置,发现band为1, 然后设置2为5G,设置完成后,再读取Softapconfig, 发现是3,所以可以确定是设置的时候直接被底层做了修正

packages/apps/Settings/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java
    
void startTether() {
        mSwitchBar.setEnabled(false);

        //验证代码
        final SoftApConfiguration config = mWifiManager.getSoftApConfiguration();
        Log.i("wqy-tethring-barcontrol", "wqy get local config band = " + config.getBand());
        mWifiManager.setSoftApConfiguration(
                new SoftApConfiguration.Builder(config).setBand(SoftApConfiguration.BAND_5GHZ)
                        .build());
        Log.i("wqy-tethring-barcontrol", "wqy after set 5G,  local config band = " + mWifiManager.getSoftApConfiguration().getBand());

        mConnectivityManager.startTethering(TETHERING_WIFI, true /* showProvisioningUi */,
                mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));
    }

然后设置softapconfig 流程到了WifiServiceImpl.java

经过测试和追踪,在此处做的修改

mWifiApConfigStore.setApConfiguration(softApConfig)
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java  
 
 public boolean setSoftApConfiguration(
            @NonNull SoftApConfiguration softApConfig, @NonNull String packageName) {
        if (WifiApConfigStore.validateApWifiConfiguration(softApConfig, privileged)) {
            mActiveModeWarden.updateSoftApConfiguration(softApConfig);
            mWifiThreadRunner.post(() -> mWifiApConfigStore.setApConfiguration(softApConfig));
            return true;
        } else {
            Log.e(TAG, "Invalid SoftAp Configuration");
            return false;
        }
    }

可以看出,WifiApConfigStore.java, 在设置2为5G的时候,并且没有设置任何信道的时候,会将2.4G也加上

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiApConfigStore.java
 
public synchronized void setApConfiguration(SoftApConfiguration config) {
        Log.i(TAG, "wqy setApConfiguration");
        if (config == null) {
            config = getDefaultApConfiguration();
        } else {
            config = sanitizePersistentApConfig(config);
        }
    }


    private SoftApConfiguration sanitizePersistentApConfig(SoftApConfiguration config) {
        SoftApConfiguration.Builder convertedConfigBuilder = null;
        Log.i(TAG, "wqy sanitizePersistentApConfig, config band = " + config.getBand());

        // some countries are unable to support 5GHz only operation, always allow for 2GHz when
        // config doesn't force channel
        if (config.getChannel() == 0 && (config.getBand() & SoftApConfiguration.BAND_2GHZ) == 0) {
            Log.w(TAG, "wqy Supplied ap config band without 2.4G, add allowing for 2.4GHz");
            if (convertedConfigBuilder == null) {
                Log.i(TAG, "wqy sanitizePersistentApConfig 1, convertedConfigBuilder is null");
                convertedConfigBuilder = new SoftApConfiguration.Builder(config);
            }
            Log.i(TAG, "wqy sanitizePersistentApConfig 2, config band = " + convertedConfigBuilder.build().getBand());
            convertedConfigBuilder.setBand(config.getBand() | SoftApConfiguration.BAND_2GHZ);
            Log.i(TAG, "wqy sanitizePersistentApConfig 3, config band = " + convertedConfigBuilder.build().getBand());
        }
        return convertedConfigBuilder == null ? config : convertedConfigBuilder.build();
    }

最后回到Settings这边对频宽的处理

当settings界面显示的时候,设置为5G的时候,这边也会将2.4G带上

理由是:一些国家不支持5G,所以需要包括2.4G

packages/apps/Settings/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java
    
public void updateDisplay() {
        final SoftApConfiguration config = mWifiManager.getSoftApConfiguration();

        boolean is5G = is5GhzBandSupported();
        Log.i(TAG, "wqy updateDisplay is5G = " + is5G);

        if (config == null) {
            mBandIndex = SoftApConfiguration.BAND_2GHZ;
            Log.d(TAG, "Updating band index to BAND_2GHZ because no config");
        } else if (is5GhzBandSupported()) {
            mBandIndex = validateSelection(config.getBand());
            Log.d(TAG, "Updating band index to " + mBandIndex);
        }

    }

    private int validateSelection(int band) {
        // unsupported states:
        // 1: BAND_5GHZ only - include 2GHZ since some of countries doesn't support 5G hotspot
        // 2: no 5 GHZ support means we can't have BAND_5GHZ - default to 2GHZ
        if (SoftApConfiguration.BAND_5GHZ == band) {
            if (!is5GhzBandSupported()) {
                return SoftApConfiguration.BAND_2GHZ;
            }
            return SoftApConfiguration.BAND_5GHZ | SoftApConfiguration.BAND_2GHZ;
        }

        return band;
    }

最终解决问题的思路:

就是将WifiApConfigStore.java里的设置整改处,将设置5G时携带2.4G的逻辑删除

你可能感兴趣的:(Wifi-蓝牙-FM,android)