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

    //参数有4个
    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<WifiClient> 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)

<integer translatable="false" name="config_wifiHardwareSoftapMaxClientCount">16</integer>

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

<integer translatable="false" name="config_wifiHardwareSoftapMaxClientCount">32</integer>

四、热点的双频合一

工作中遇到别人提的一个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的逻辑删除

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 要在Appium中设置WiFi,可以使用以下命令来开启或关闭WiFi。开启WiFi的命令是:adb shell am broadcast -a io.appium.settings.wifi -n io.appium.settings/.receivers.WiFiConnectionSettingReceiver --es setstatus enable,关闭WiFi的命令是:adb shell am broadcast -a io.appium.settings.wifi -n io.appium.settings/.receivers.WiFiConnectionSettingReceiver --es setstatus disable。请注意,这些命令必须在启动driver之前执行,否则可能会导致目标app出现ANR错误。此外,需要注意不同厂商可能会有限制,所以在特定设备上的效果需要进行确认。\[1\] 另外,还有一种思路是通过Appium UI操作来开启或关闭WiFi。首先,使用以下命令打开WiFi页面:adb shell am start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings。然后,根据当前网络情况进行判断,如果可以ping通百度,则通过UI操作关闭WiFi,再打开WiFi;如果无法ping通,则通过UI操作打开WiFi。这种方法需要进行验证。\[2\] 还有一种思路是在10.0系统的产品开发中,通过修改默认设置来保证升级成功。具体操作是在Settings中的WiFi详情页,找到隐私选项,并将默认选中设备的MAC地址的功能进行分析和实现。这种方法适用于需要固定使用本机MAC地址的情况。\[3\] #### 引用[.reference_title] - *1* *2* [【Appium踩坑】使用Appium Setting开启wifi or 关闭wifi,弹系统wifi权限弹窗问题](https://blog.csdn.net/YUICUI/article/details/123778853)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Android Settings 中wifi详情页 隐私默认选中设备mac](https://blog.csdn.net/baidu_41666295/article/details/122377557)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值