Android13 wifi状态问题分析

Android13 wifi状态问题分析

一、wifi开关设置默认状态无效

场景;

设置wif 默认开关属性:


framework\base\packages\SettingsProvider\res\values\defaults.xml
//设置默认开关状态
<bool name="def_wifi_on">false</bool>

系统升级后,wifi 默认设置属性无效。

原因:

多个地方存在定义默认wifi开关状态的定义。

解决方法:

可能是配置文件,有overlay,一般是在 vendor 下面有 WifiOverlay的情况,或者全局查找,使用命令查找:

find . -name "*.xml" | xargs grep "def_wifi_on"

看看系统源码哪里还会设置默认状态的文件

比如 amlogic 方案下面会存在overlay属性:

vendor/amlogic/common/apps/VendorOverlay/WifiOverlay/res/values/defaults.xml

二、wifi 开关状态不记忆

这个比较少见,感觉是系统缓存策略问题。偶现的。在手机上基本不可能出现,板子上调试可能会出现。

场景:

wifi 开关状态从开启到关闭后,再断电关机然后上电开机后,wifi 的开关状态会变成打开。

通过几次测试发现,只有关闭状态会不记忆,开启状态是记忆的。
目前只在Android13 amlogic 方案上见过。

//wifi 开关后使用名称查看,状态是正常的
settings get global wifi_on //0关闭,1开启

明明关闭后,并且查询到 wifi_on 属性值为 0 ,硬重启后,查询 wifi_on 属性值为 1,wifi 处于开启状态。

你可能怀疑数据没写入到系统文件,但是查看系统文件是写入成功的

可以命令查看:


cat /data/system/users/0/settings_global.xml  | grep wifi_on

上面需要root 权限才能看system目录

可能原因:

硬重启的情况,内存数据未成功保存到flash中导致。网上搜的!

解决方法:

adb shell 多次输入命令 :sync,目的就是强制把内存中待写入的数据强制刷入flash中。

实际代码中,执行开关状态后 sync命令即可。

但是测试几次发现,执行关闭wifi后,马上执行sync 不一定有用,需要一段时间后(比如5秒)再执行可以生效。


//同步sync ,需要系统签名权限
private void fileSync() {
    Runtime runtime = Runtime.getRuntime();
    try {
        runtime.exec("sync");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

这个问题比较特殊,这样看其他属性设置也会有概率有这个问题,
所以要小心,最好是看看系统内存策略哪里能进行优化处理。

三、wifi未自动重连问题

场景:

1、连接某个wifi,开关wifi 后,未自动连接之前连接的wifi
2、连接某个wifi,再连接一个wifi,断开当前连接的WiFi,未自动连接之前连接的wifi

问题原因:

Android 默认的校验机制,无法访问google的情况或者连接连接网络比较慢的情况,会设置该wifi 默认不进行自动连接状态。

我这里开发的是Android13 才发现的。其他版本也可能出现,估计要看供应商是否适配过吧。

对比一下日志:

logcat | grep NetworkMonitor

//isSuccessful()=false  不会自动重连的wifi 的日志
04-27 15:03:59.347  1198  4081 D NetworkMonitor/110: checkAndRenewResourceConfig: update captive portal https urls to [https://www.google.com/generate_204]
04-27 15:03:59.348  1198  4081 D NetworkMonitor/110: checkAndRenewResourceConfig: update captive portal http urls to [http://connectivitycheck.gstatic.com/generate_204]
04-27 15:03:59.350  1198  4081 D NetworkMonitor/110: checkAndRenewResourceConfig: update captive portal fallback urls to[http://www.google.com/gen_204, http://play.googleapis.com/generate_204]
04-27 15:03:59.350  1198  4081 D NetworkMonitor: Starting on network 110 with capport HTTPS URL [https://www.google.com/generate_204] and HTTP URL [http://connectivitycheck.gstatic.com/generate_204]
04-27 15:03:59.681  1198  1381 D UpstreamNetworkMonitor: New default Internet network: 110
04-27 15:03:59.723  1198  4094 D NetworkMonitor/110: PROBE_DNS connectivitycheck.gstatic.com 61ms OK 14.215.177.38
04-27 15:03:59.847  1198  4093 D NetworkMonitor/110: PROBE_DNS www.google.com 194ms OK 157.240.10.32
04-27 15:04:09.846  1198  4094 D NetworkMonitor/110: PROBE_HTTP http://connectivitycheck.gstatic.com/generate_204 Probe failed with exception java.net.SocketTimeoutException: timeout
04-27 15:04:09.961  1198  4093 D NetworkMonitor/110: PROBE_HTTPS https://www.google.com/generate_204 Probe failed with exception java.net.SocketTimeoutException: Read timed out
04-27 15:04:12.733  1198  4092 D NetworkMonitor/110: PROBE_FALLBACK http://www.google.com/gen_204 Probe failed with exception java.net.SocketTimeoutException: timeout
04-27 15:04:12.741  1198  4092 D NetworkMonitor/110: isCaptivePortal: isSuccessful()=false isPortal()=false RedirectUrl=null isPartialConnectivity()=false Time=13089ms


//isSuccessful()=true 会自动重连的wifi 的日志
04-27 15:05:33.154  1198  4882 D NetworkMonitor/111: checkAndRenewResourceConfig: update captive portal https urls to [https://www.google.com/generate_204]
04-27 15:05:33.155  1198  4882 D NetworkMonitor/111: checkAndRenewResourceConfig: update captive portal http urls to [http://connectivitycheck.gstatic.com/generate_204]
04-27 15:05:33.155  1198  4882 D NetworkMonitor/111: checkAndRenewResourceConfig: update captive portal fallback urls to[http://www.google.com/gen_204, http://play.googleapis.com/generate_204]
04-27 15:05:33.155  1198  4882 D NetworkMonitor: Starting on network 111 with capport HTTPS URL [https://www.google.com/generate_204] and HTTP URL [http://connectivitycheck.gstatic.com/generate_204]
04-27 15:05:33.787  1198  1381 D UpstreamNetworkMonitor: New default Internet network: 111
04-27 15:05:34.095  1198  4900 D NetworkMonitor/111: PROBE_DNS www.google.com 335ms OK 142.250.207.100
04-27 15:05:34.128  1198  4901 D NetworkMonitor/111: PROBE_DNS connectivitycheck.gstatic.com 370ms OK 142.250.206.195

04-27 15:05:36.355  1198  4900 D NetworkMonitor/111: PROBE_HTTPS https://www.google.com/generate_204 time=2257ms ret=204 request={Connection=[close], User-Agent=[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.32 Safari/537.36]} headers={null=[HTTP/1.1 204 No Content], Alt-Svc=[h3=":443"; ma=2592000,h3-29=":443"; ma=2592000], Connection=[close], Content-Length=[0], Cross-Origin-Resource-Policy=[cross-origin], Date=[Thu, 27 Apr 2023 07:05:36 GMT], X-Android-Received-Millis=[1682579136352], X-Android-Response-Source=[NETWORK 204], X-Android-Selected-Protocol=[http/1.1], X-Android-Sent-Millis=[1682579135355]}
04-27 15:05:36.358  1198  4899 D NetworkMonitor/111: isCaptivePortal: isSuccessful()=true isPortal()=false RedirectUrl=null isPartialConnectivity()=false Time=2602ms


从日志可以看到网络种默认访问的网址,
并且第一个wifi,是出现有timeout 的情况,需要时间十几秒,第二个是正常的情况,一般两三秒就可以。

解决方法:

参考:
https://blog.csdn.net/weixin_44008788/article/details/115798135
https://blog.csdn.net/woaiminghui/article/details/128412017
https://wuyaogexing.com/70/178360.html

上面几个其实没写明白,只是简单说了一下!

解决方法1:

修改 网络默认访问的网址。


packages/modules/NetworkStack/res/values/config.xml

    //默认访问超时时间,12.5秒
     <integer name="default_captive_portal_dns_probe_timeout">12500</integer>

     <!-- HTTP URL for network validation, to use for detecting captive portals. -->
-    <string name="default_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.com/generate_204</string>
+    <string name="default_captive_portal_http_url" translatable="false">http://xxxxx/generate_204</string> //修改为可以访问的网址

没试过,估计是可行的

解决方法2:

分析修改 Android 网络连接评测机制:

//Android 13 中的 NetworkMonitor 位置:
packages\modules\NetworkStack\src\com\android\server\connectivity\NetworkMonitor.java

//网上有说这里直接返回 success的情况即可。
private CaptivePortalProbeResult isCaptivePortal(ValidationProperties properties, URL[] httpsUrls, URL[] httpUrls, URL fallbackUrl) {
    //return XXX;
}


估计是和网上的系统版本代码不一样了,不能一样的修改,怕改得不对!
但是,花点时间理清楚逻辑肯定是能修改的。
在 NetworkMonitor 这个类也能看到网络请求的逻辑,并且网络请求返回的情况,并做对应判断。

从上面日志和属性保存情况,我猜测修改某个属性就可以了,所以我使用的是自创的一种写法;

解决方法2:

修改 isSuccessCode 方法返回 true 即可。

//Android 13 中的 CaptivePortalProbeResult 位置:
packages\modules\NetworkStack\common\captiveportal\src\android\net\captiveportal\CaptivePortalProbeResult.java

import android.os.SystemProperties;
import android.util.Log;

    private static boolean isSuccessCode(int responseCode) {
        boolean isNotCheckNetWork = SystemProperties.getBoolean("persist.sys.not_monitor", true); //默认为 true
        Log.i("CaptivePortalProbeResult", "isSuccessCode responseCode = " + responseCode);
        if (isNotCheckNetWork) {
            return true;
        } else {
            return responseCode == SUCCESS_CODE; //之前的逻辑
        }
    }

上面我是添加了 prop 属性判断,默认设置跳过网络验证,后期可以关闭。

第二种方法,亲测是真实有效的。

4、其他

Android wifi 启动流程

https://blog.csdn.net/TSK_Amine/article/details/126057653

//Android 13  WifiServiceImpl 是放到package 下面了!
packages\modules\Wifi\service\java\com\android\server\wifi\WifiServiceImpl.java

    public void checkAndStartWifi() {
        mWifiThreadRunner.post(() -> {
            if (!mWifiConfigManager.loadFromStore()) {
                Log.e(TAG, "Failed to load from config store");
            }
            。。。
            // Check if wi-fi needs to be enabled
            boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
            
            //这里默认会打印wifi 开关状态,其实就是setting.global_wifi_on 的属性值!
            Log.i(TAG, "WifiService starting up with Wi-Fi " + (wifiEnabled ? "enabled" : "disabled")); 
            。。。
        }
    }

猜你喜欢

转载自blog.csdn.net/wenzhi20102321/article/details/130411508