当前位置: 首页 > news >正文

Android13 命令启用WLAN详细日志分析

Android13 命令启用WLAN详细日志分析

文章目录

  • Android13 命令启用WLAN详细日志分析
    • 一、前言
    • 二、开启“启动WLAN详细日志记录功能”分析过程
      • 1、settings和prop属性分析
      • 2、查看wifi服务开始的地方 WifiServiceImpl.java
      • 3、WifiSettingsConfigStore.get分析
      • 4、 WifiConfigStore.xml 保存属性的地方
      • 5、WifiManager 打开“启动WLAN详细日志记录功能”
    • 三、其他
      • 1、“启动WLAN详细日志记录功能”小结
      • 2、开启“启动WLAN详细日志记录功能” 状态cmd命令
      • 3、Android 使用adb操作WiFi连接扫描等相关指令
      • 4、Android 拉起开发者设置界面命令和代码实现
      • 5、开启“启动WLAN详细日志记录功能” 状态的日志区别
        • (1)WifiService日志:
        • (2) WifiNetworkSelector 日志

一、前言

Android 如果遇到wifi问题,比如无法联网,连接wifi失败,热点异常等问题;

如果查看wifi相关日志未发现具体异常,可以通过更加详细的wifi日志,

查看wifi具体过程,可以使用“启动WLAN详细日志记录功能”,看看是否能发现有用的线程。

Android开发者模式“启动WLAN详细日志记录功能”,这个没啥好说的,

原生Settings,进入开发者界面,打开开关就行了。
如下图所示(英文):
在这里插入图片描述

中文:
在这里插入图片描述

本文主要介绍一下,如果没有原生Settings,或者没有界面的情况,如何打开“启动WLAN详细日志记录功能”功能呢?

网上搜索到的说法:

# 查询WLAN详细日志开关值
adb shell settings get global wifi_verbose_logging_enabled# 启用WLAN详细日志
adb shell settings put global wifi_verbose_logging_enabled 1# 禁用WLAN详细日志
adb shell settings put global wifi_verbose_logging_enabled 0

看起来是挺ok 的,但是试了下不行,可能Android9之前的系统可以。

并且在原生设置的开发者界面打开“启动WLAN详细日志记录功能”,上面的Settings属性查询是没有变化的。

所以本文分析一下是哪个属性或者命令可以控制“启动WLAN详细日志记录功能”。

目前网上没看到任何一个文章对这个开关属性进行分析。

整体还是比较有用的,收藏一下是没错的。

二、开启“启动WLAN详细日志记录功能”分析过程

如果不想看分析过程可以直接看后面总结!

因为“启动WLAN详细日志记录功能” 开启后,重启是记忆的,那么一般是settings属性或者prop属性记忆。

1、settings和prop属性分析

通过对比“启动WLAN详细日志记录功能” 开、关状态的prop属性,和settings发现居然没有差别。

获取开、关不同状态的属性做对比:

获取prop属性,获取系统所有prop属性:
getprop获取settings的 各个属性:
settings list global
settings list system
settings list secury查看settings属性的源文件
cat /data/system/users/0/settings_global.xml

说明:settings global wifi_verbose_logging_enabled 属性并不是“启动WLAN详细日志记录功能”相关的。

并且设置命令:adb shell settings put global wifi_verbose_logging_enabled 1

发现“启动WLAN详细日志记录功能”开关还是关闭的,重启s设备验证查看也是关闭的。

通过logcat查看wifi相关日志并没有增加日志。

难道不是通过属性记忆的,直接保存在某个文件?奇怪!

2、查看wifi服务开始的地方 WifiServiceImpl.java

packages/modules/Wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

    //(1)准备启动wifi前的基本判断public void checkAndStartWifi() {mWifiThreadRunner.post(() -> {//(2)这里是最关键的“启动WLAN详细日志记录功能”读取属性,并设置全局属性的代码// config store is read, check if verbose logging is enabled.enableVerboseLoggingInternal(
mWifiInjector.getSettingsConfigStore().get(WIFI_VERBOSE_LOGGING_ENABLED)? 1 : 0);// Check if wi-fi needs to be enabledboolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();Log.i(TAG,"WifiService starting up with Wi-Fi " + (wifiEnabled ? "enabled" : "disabled"));
...}//(3)类型各处打印都是通过这个判断后决定是否打印的, mVerboseLoggingLevel 属性是关键private boolean isVerboseLoggingEnabled() {return mFrameworkFacade.isVerboseLoggingAlwaysOn(getVerboseAlwaysOnLevel(), mBuildProperties)|| WifiManager.VERBOSE_LOGGING_LEVEL_DISABLED != mVerboseLoggingLevel;}//(4)获取res属性的值(默认0)!这个是固定的需要编译apk,所以这个不是开关的关键。private int getVerboseAlwaysOnLevel() {if (mVerboseAlwaysOnLevel == -1) {mVerboseAlwaysOnLevel = mContext.getResources().getInteger(R.integer.config_wifiVerboseLoggingAlwaysOnLevel);}return mVerboseAlwaysOnLevel;}//(5)设置wifi调试等级的暴露方法,0关,1开@Overridepublic void enableVerboseLogging(int verbose) {enforceAccessPermission();enforceNetworkSettingsPermission();mLog.info("enableVerboseLogging uid=% verbose=%").c(Binder.getCallingUid()).c(verbose).flush();boolean enabled = verbose > 0;mWifiInjector.getSettingsConfigStore().put(WIFI_VERBOSE_LOGGING_ENABLED, enabled);onVerboseLoggingStatusChanged(enabled);enableVerboseLoggingInternal(verbose); //这里是设置wifi相关的类都打开debug日志。}//获取wifi调试等级的暴露方法,0关,1开@Overridepublic int getVerboseLoggingLevel() {if (isVerboseLoggingEnabled()) {mLog.info("getVerboseLoggingLevel uid=%").c(Binder.getCallingUid()).flush();}return mVerboseLoggingLevel;}

从上面第二点(2)查看,getSettingsConfigStore().get(WIFI_VERBOSE_LOGGING_ENABLED)

看起来就是从Settings里面获取 WIFI_VERBOSE_LOGGING_ENABLED 属性。

看下Settings 的源码:

frameworks/base/core/java/android/provider/Settings.java/*** Setting to enable verbose logging in Wi-Fi; disabled by default, and setting to 1* will enable it. In the future, additional values may be supported.* @hide* @deprecated Use {@link WifiManager#setVerboseLoggingEnabled(boolean)} for setting the* value and {@link WifiManager#isVerboseLoggingEnabled()} for query.*/@Deprecated@Readablepublic static final String WIFI_VERBOSE_LOGGING_ENABLED ="wifi_verbose_logging_enabled";...
MOVED_TO_GLOBAL.add(Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED);

这个不就是 settings global wifi_verbose_logging_enabled 属性吗,为啥实际没有作用!!!

具体原因还要分析:WifiServiceImpl 的 getSettingsConfigStore().get(WIFI_VERBOSE_LOGGING_ENABLED) 的具体实现。

3、WifiSettingsConfigStore.get分析

这里的 getSettingsConfigStore() 获取的是 WifiSettingsConfigStore 对象。

WifiSettingsConfigStore.java 源码查看:

packages/modules/Wifi/service/java/com/android/server/wifi/WifiSettingsConfigStore.javapublic class WifiSettingsConfigStore {private static final String TAG = "WifiSettingsConfigStore";// List of all allowed keys.private static final ArrayList<Key> sKeys = new ArrayList<>();private final Map<String, Object> mSettings = new HashMap<>();/*** Setting to enable verbose logging in Wi-Fi; disabled by default, and setting to 1* will enable it. In the future, additional values may be supported.*/public static final Key<Boolean> WIFI_VERBOSE_LOGGING_ENABLED =new Key<>("wifi_verbose_logging_enabled", false);/*** The Wi-Fi peer-to-peer device name*/public static final Key<String> WIFI_P2P_DEVICE_NAME =new Key<>("wifi_p2p_device_name", null);...public <T> void put(@NonNull Key<T> key, @Nullable T value) {synchronized (mLock) {mSettings.put(key.key, value);}triggerSaveToStoreAndInvokeListeners(key);}public @Nullable <T> T get(@NonNull Key<T> key) {synchronized (mLock) {return (T) mSettings.getOrDefault(key.key, key.defaultValue);}}private <T> void triggerSaveToStoreAndInvokeListeners(@NonNull Key<T> key) {mHandler.post(() -> {mHasNewDataToSerialize = true;mWifiConfigManager.saveToStore(true); //wifi配置保存的关键!invokeListeners(key);});}
}

从上面源码可以看出:

1、getSettingsConfigStore().get(WIFI_VERBOSE_LOGGING_ENABLED)并不是直接从Settings里面获取的属性值;
2、get(WIFI_VERBOSE_LOGGING_ENABLED)是从键值对中获取到属性值;
3、键值对的属性值,就要看put调用了,哪些过程初始化会调用put?
4、还有种情况就是没有默认put,直接获取到就是false的。

分析了WifiSettingsConfigStore.java 好像看不出 WIFI_VERBOSE_LOGGING_ENABLED 属性的获取是从哪里来的。

再分析了:WifiService、WifiServiceImpl、WifiInjector、WifiMetrics 初始化和设置Settings属性过程;

还是没看到 WIFI_VERBOSE_LOGGING_ENABLED 初始化的地方。

所以大概可以得出结论,WIFI_VERBOSE_LOGGING_ENABLED 属性默认是没有设置的,默认为false。

但是如果设置的了一次true,他是保存到哪里的呢?

重点就是上面的 WifiSettingsConfigStore 的代码了:

mWifiConfigManager.saveToStore(true); //wifi配置保存的关键!

这里看不出文件保存的路径,但是一直追溯是可以发现保存文件的,就是Wifi的配置文件;

Wifi的连接、断开、Wifi配置信息都会调用这个进行数据保存到本地配置文件 WifiConfigStore.xml 。

所以基本可以确定: “启动WLAN详细日志记录功能” 的开关状态就是保存在 WifiConfigStore.xml 文件中。

4、 WifiConfigStore.xml 保存属性的地方

在运行环境中wifi保存配置属性查看:

cat /data/misc/apexdata/com.android.wifi/WifiConfigStore.xml  
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<WifiConfigStoreData>
<NetworkList> //多个保存的Wifi
<Network> //其中一个
<WifiConfiguration>
<string name="ConfigKey">&quot;NO-BUG&quot;WPA_PSK</string> //Wifi名称
<string name="SSID">&quot;NO-BUG&quot;</string> //Wifi名称
<string name="PreSharedKey">&quot;qwertyuiop&quot;</string> //Wifi密码...
//“启动WLAN详细日志记录功能”状态,默认是没有的!
<boolean name="wifi_verbose_logging_enabled" value="true" /> 
<string name="wifi_last_country_code">US</string>
<int name="supplicant_hal_aidl_service_version" value="2" />
</WifiConfigStoreData>

所以可以得出结论 “启动WLAN详细日志记录功能” 的开关状态就是保存在 WifiConfigStore.xml 文件中。

另外还可以在 WifiConfigStore.xml 文件看到Wifi的密码,这个Wifi密码在系统API中是没有暴露的,只能校验。

所以如果需要获取已保存的Wifi的密码也是可以通过获取 WifiConfigStore.xml 文件内容得到。

分析的过程完了?

差不多吧,但是还是差点!

因为这里还没说怎么设置默认开启!

5、WifiManager 打开“启动WLAN详细日志记录功能”

上面在 WifiServiceImpl.java 源码中看到有暴露的方法 enableVerboseLogging,所以猜测 WifiManager 是有api的。

源码查看:

packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java

    /*** Verbose logging mode: DISABLED.* @hide*/@SystemApipublic static final int VERBOSE_LOGGING_LEVEL_DISABLED = 0;/*** Verbose logging mode: ENABLED.* @hide*/@SystemApipublic static final int VERBOSE_LOGGING_LEVEL_ENABLED = 1;@SystemApi@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)public void setVerboseLoggingLevel(@VerboseLoggingLevel int verbose) {enableVerboseLogging(verbose);}@RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)public void enableVerboseLogging(@VerboseLoggingLevel int verbose) {try {mService.enableVerboseLogging(verbose);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}@SystemApipublic boolean isVerboseLoggingEnabled() {return getVerboseLoggingLevel() > 0;}

上面源码看到有查看和设置 “启动WLAN详细日志记录功能” 的暴露api方法。

所以系统应用调用 WifiManager.enableVerboseLogging(1) 就可以设置打开“启动WLAN详细日志记录功能” 。

因为这个设置后是保存在本地文件的,所以重启是会生效的。

wifi服务开始的地方 WifiServiceImpl.java 会判断是否 “启动WLAN详细日志记录功能” ,进行打印一些详细数据。

上面一顿分析发现, “启动WLAN详细日志记录功能” 状态 是保存在 WifiConfigStore.xml 文件。

但是没有好像没有命令可以直接修改 WifiConfigStore.xml 的内容,难道要pull 出来,修改后,push进去?

其实是有方法的,cmd wifi命令就可以,往后看看。

三、其他

1、“启动WLAN详细日志记录功能”小结

(1)adb shell settings put global wifi_verbose_logging_enabled 1 //并不能启用WLAN详细日志
(2)“启动WLAN详细日志记录功能” 状态属性并未保存在settings文件中
(3)“启动WLAN详细日志记录功能” 状态 是保存在 WifiConfigStore.xml 文件
(4)WifiManager.enableVerboseLogging(1) 开启“启动WLAN详细日志记录功能” 状态

2、开启“启动WLAN详细日志记录功能” 状态cmd命令

查询、开启和关闭 wifi详情日志开关的命令示例:

console:/ # cmd wifi is-verbose-logging //查询wifi详情日志开关 ,显示关闭
disabled
console:/ # console:/ # cmd wifi set-verbose-logging enabled //开启wifi详情日志开关
console:/ # cmd wifi is-verbose-logging //查询wifi详情日志开关,显示开启
enabled
console:/ #console:/ # cmd wifi set-verbose-logging disabled //关闭wifi详情日志开关
console:/ # 
console:/ # cmd wifi is-verbose-logging//查询wifi详情日志开关 ,显示关闭 
disabled
console:/ # 

为啥 cmd wifi 命令可以控制 开启“启动WLAN详细日志记录功能” ?

因为 系统中定义了 WifiShellCommand 一直在监听 cmd wifi的命令,

输入对应的参数后就可以调用 WifiManager 暴露的大部分api方法。

下面是控制wifi的adb命令详细介绍。

3、Android 使用adb操作WiFi连接扫描等相关指令

Android系统自带有组很强大的shell指令集,

这里记录下平时使用的cmd wifi 相关指令。

系统初期开发或者定位一下wifi、热点问题会比较有用。

本文不仅详细介绍cmd wifi相关用法,并且后续有介绍系统Java代码中具体控制位置,

如果有特殊需求可以对命令进行扩展定制。

原文链接:https://blog.csdn.net/wenzhi20102321/article/details/140043930

4、Android 拉起开发者设置界面命令和代码实现

Android进入Android开发者选项,一般步骤是:

1、原生设置--》关于--》点击七次“版本号”条目 (会提示:已打开开发者选项)
2、返回主界面--》系统设置--》开发者设置界面

命令:

//(1)打开开发者选项开关:
settings put global development_settings_enabled 1 //(2)am通过action或者fragment拉起开发者设置界面
am start -a android.settings.APPLICATION_DEVELOPMENT_SETTINGS
//或者
am start -a com.android.settings.APPLICATION_DEVELOPMENT_SETTINGS

文链接:https://blog.csdn.net/wenzhi20102321/article/details/146985730

5、开启“启动WLAN详细日志记录功能” 状态的日志区别

上面只是一顿分析,但是没看到实际效果日志,下面简单举例一下logcat日志。

(1)WifiService日志:
logcat | grep WifiService//未开启详细日志打印开关前日志:
09-09 21:20:48.890   924  2424 I WifiService: setWifiEnabled package=com.skg.settings uid=1000 enable=true isPrivileged=true
09-09 21:20:48.995   924  2161 I WifiService: startScan uid=1000
09-09 21:20:59.004   924  2161 I WifiService: startScan uid=1000//打开wifi详情的日志:
09-09 21:26:45.394   924  1916 I WifiService: enableVerboseLogging uid=1000 verbose=1//开启详细日志打印开关后日志:
09-09 21:26:45.919   924  2425 I WifiService: getWifiEnabledState uid=1000 state=1
09-09 21:26:46.423   924  1690 I WifiService: setWifiEnabled package=com.skg.settings uid=1000 enable=true isPrivileged=true
09-09 21:26:46.425   924  1690 I WifiService: getWifiEnabledState uid=10127 state=2
09-09 21:26:46.426   924  1690 I WifiService: getWifiEnabledState uid=1000 state=2
09-09 21:26:46.426   924  1690 I WifiService: getWifiEnabledState uid=1000 state=2
09-09 21:26:46.514   924  2425 I WifiService: getWifiEnabledState uid=1000 state=3
09-09 21:26:46.514   924  1054 I WifiService: startScan uid=1000
09-09 21:26:46.515   924  1690 I WifiService: getWifiApEnabledState uid=1000
...

未打开“启动WLAN详细日志记录功能”前,WifiService 只会打印Wifi开关状态的变化等简单日志;

打开“启动WLAN详细日志记录功能”后,WifiService 会打印Wifi开关状态的过程日志,正常是:打开中,打开完成;

如果发现只有打开中,未看到打开完成状态,那么就可以从打开中的状态往后看看,具体是哪里异常导致未打开完成。

(2) WifiNetworkSelector 日志

WifiNetworkSelector 是从wifi列表中选择哪个wifi进行默认连接的重要类。

日过没有打开“启动WLAN详细日志记录功能” 是没有 WifiNetworkSelector 相关日志打印的,

打开了“启动WLAN详细日志记录功能” ,才会有相关日志。

console:/ # logcat | grep WifiNetworkSelector09-11 06:33:40.496   925  1154 D WifiNetworkSelector: Networks filtered out due to low signal strength: AndroidAP-5301:9e:b8:b4:82:a3:14(5GHz)-82 / 
...
09-11 06:33:40.502   925  1154 D WifiNetworkSelector: removeAutoUpgradeSecurityParamsIfNecessary: SSID: "xm5G" baseSecurityType: 0 upgradableSecurityType: 6 isLegacyNetworkInRange: true isUpgradableTypeOnlyInRange: false isAutoUpgradeEnabled: true
09-11 06:33:40.504   925  1154 D WifiNetworkSelector: ThroughputScorer chooses 0 score 3624.962+/-10.0 expid 42330058

还有其他Wifi相关类也是根据是否打开“启动WLAN详细日志记录功能”,决定是否打印一些详细日志,

比如:WifiConnectivityManager、NetworkProviderSettings、WifiSettings、AccessPoint、WifiP2pServiceImpl 等等等。

http://www.dtcms.com/a/390868.html

相关文章:

  • 临床AI产品化全流程研究:环境聆听、在环校验与可追溯系统的多技术融合实践(中)
  • 深度解读昇腾CANN动态Shape图调度加速技术
  • linux系统使用ImageMagick注意,只能使用convert命令
  • [Windows] 搜狗拼音一键净化
  • Go语言25个关键字全解析
  • 图像滤波常用总结
  • Go语言设计原则与设计模式
  • (LoRA深度解析)LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS论文精读(逐段解析)
  • 第十四届蓝桥杯青少组C++选拔赛[2022.11.27]第二部分编程题(4、找路线)
  • 知识图谱对自然语言处理深层语义分析的影响与启示:结构化研究报告
  • 架构师成长之路-缓存二
  • 正点原子小智BOX0/BOX2 产品使用视频表情功能
  • 鸿蒙NEXT分布式文件系统:开启跨设备文件访问新时代
  • 【主机初始化工作】
  • Ubuntu20.04仿真 | iris四旋翼添加livox mid360激光雷达
  • Linux进程终止
  • Go如何重塑现代软件开发的技术基因
  • 设计模式(C++)详解—外观模式(2)
  • 【ubuntu24.04】apt update失败 过期的签名清理
  • Go 语言常用算法库教学与实践指南
  • 基于FPGA的智能垃圾分类装置
  • 168. Excel 表列名称【简单】
  • Ubuntu20.04 6步安装ROS-Noetic
  • 基于 MATLAB 的双边滤波去图像云雾处理
  • 将一台已连接无线网络的 Windows 电脑通过网络线共享网络给另一台电脑
  • 复习1——TCP/IP之常用协议
  • 讲清楚 PagedAttention
  • 多对多依赖;有向无环图l;拓扑排序;DFS回溯输出全路径简述
  • 【序列晋升】37 Spring Data LDAP 跳出传统数据访问框架,掌握目录服务开发新范式
  • Redis三种服务架构