AOSP Settings模块问题初窥

本文来源于本人在工作组内分享,源码、公司部分以做加密、模糊处理 ,旨在分享在Android中对于Settings设置模块的问题分析思路、案例分析等。

目录

一、实际常用工具

ADB常用命令

[Jadx 反编译工具](#Jadx 反编译工具)

grep、find搜索文件/代码

HierarchyViewer

MediatekDBViwer

二、问题分析思路

问题分析思路

UI类问题

需求类问题

功能类问题

ANR问题

三、典型问题案例

从简单UI问题举例

固定拨号列表界面无法横屏

无障碍功能菜单,点击设置,底部空缺显示黑色

[设置下 有中文(台湾)字样](#设置下 有中文(台湾)字样)

设置-个性化-颜色菜单位置有误

视频模式的环绕声默认为近场,与预期结果不符

合入沙特国家需求

偶现铃声设置为空


一、实际常用工具

以下这些工具我会后续出其他文章进行详解

  • ADB:安装设置APK、查询APK版本包名当前Activity等
  • HierarchyViewer:对比Uiautomatorviewer,Hierarchy Viewer具有实时性、可视化优势
  • Jadx 反编译工具:设置中会动态添加一些APK,例如定时关机、隐私、电量实验室等,部分情况需要验证资源
  • MediatekDBViwer:用于分析SWT/ANR问题,可以查看CPU、低内存、IO等情况
  • grep、find组合:无论是VSCode、Windows搜索都会有偏差、速度慢劣势,grep/find无疑是最常用手段

ADB常用命令

复制代码
查看当前界面的app的包名
adb shell dumpsys window | findstr mCurrentFocus
查找apk对应的路径
adb shell pm path <包名>
导出apk
adb pull <apk路径> <导出位置>
查看apk包名版本
adb shell dumpsys package 包名 | findstr version
adb设置状态栏秒数(方便LOG)
adb shell settings put secure clock_seconds 1
adb查看SQLite数据库
sqlite3 <数据库文件名>(先通过shell进入到SQLite数据库所在的目录,通常是在/data/data/<包名>/databases/下)
adb安装APK
adb install apk路径

Jadx 反编译工具

jadx 是一款功能强大的反编译工具,可以反编译APK、反编译jar包,前者在实际中用途广泛 一般用于查看AndroidManifest、资源文件(字符串是否包含等) 打开jadx工具--文件--选择apk即可

grep、find搜索文件/代码

grep是根据文件的内容进行查找,会对文件的每一行按照给定的模式进行匹配查找

find是根据文件的属性进行查找,如文件名,文件大小,所有者,所属组,是否为空,访问时间,修改时间 所以通常我们将这两者结合使用

HierarchyViewer

1、本地安装SDK目录->sdk->tools->hierarchyviewer.bat(版本低,可能有未知bug)或点击同级目录的monitor.bat

2、Android Studio : 工具栏->Tools->Android->Android Device Monitor(官方推荐)

3、在命令行输入 hierarchyviewer(可用,但是启动的是版本低的)

MediatekDBViwer

DB常用文件说明

|-----------------------------------------------|-------------------------------------------------------|
| FileName | Info |
| __exp_main.txt | 该文件包含程序运行中发生的异常汇总信息,通常用于调试和分析错误。 |
| SYS_BINDER_INFO | 提供有关Binder IPC机制的信息,包括失败的事务、超时和成功的事务日志,有助于调试跨进程通信的问题。 |
| SYS_CPU_INFO | 提供CPU的实时使用情况和性能指标,帮助开发人员监控和优化应用程序的CPU使用率。 |
| SYS_FILE_SYSTEMS | 系统存储空间信息 (df) |
| SYS_MEMORY_INFO/ DUMPSYS_MEMINFO SYS_PROCRANK | 系统memory使用信息 |
| SYS_PROCESSES_AND_THREADS | 列出系统中当前运行的进程和线程的详细信息,帮助开发人员监控应用程序的运行状态 |
| SYS_PROPERTIES | 系统属性信息 |

二、问题分析思路

问题分析思路

UI类问题

需求类问题

功能类问题

ANR问题

​​​​​​​

三、典型问题案例

从简单UI问题举例

固定拨号列表界面无法横屏

平板项目需要该界面横屏适配,在代码中判断平板进行更改属性值

java 复制代码
public static final boolean xx_TABLET_TYPE="tablet".equals(SystemProperties.get("ro.product.type"));
public void onCreate(...){
    if(xx_TABLET_TYPE){
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_BEHIND);    
    }else{
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);   
    }
}

无障碍功能菜单,点击设置,底部空缺显示黑色

XML 复制代码
为主题设置属性
<item name="android:navigationBarColor">颜色</item>

设置下 有中文(台湾)字样

锁定逻辑代码,在遍历列表代码中替换字样

java 复制代码
    ArrayList<Pair<String,Locale>>entryPairs=new Arrary<Pari<String,Locale>>(availableLangs.size());
    for(int i=0;i<availableLangs.size();i++){
        Locale locale=mEnginesHelper.parseLocaleString(availableLangs.get(i));
        if(locale!=null){
            if(("中文(台湾)".equals(locale.getDisplayName())||("中文(台湾)".equals(locale.getDisplayName())){
                entryPairs.add(new Pair<String,Locale>("中国(繁体)",locale));            
            }
            //...正体 香港  
        }
    }

设置-个性化-颜色菜单位置有误

通过菜单名称检索资源文件、再去检索到了逻辑代码,是三方将包名进行了修改

java 复制代码
protected boolean dynamicBindPreference(PreferenceScreen screen,Preference preference,Tile tile){
    //start
    if(TextUtils.equals("com.android.wallper/com.android.wallper.picker.CustomizationPickerActivity",tile.getDescription())){
    //end
        PreferenceCategory category=screen.findPreference("...xxx_category_key");
        if(category!=null){
            category.addPreference(preference);    
        }else{
            screen.addPreference(preference);    
        }
        return true;            
    }
    return super.dynamicBindPreference(screen,preference,tile);
}

不支持电子说明书项目,用户反馈菜单应该在重置手机下方

通过其他相同问题,确定代码位置,添加国家代码

java 复制代码
Settings/src/com/android/settings/SystemDashboardFargemnet.java
private int getVisiblePreferenceCount(PreferenceGroup group){
    int visibleCount=0;
    for(int i=0;i<group.getPreferenceCount();i++){
        final Preference preference =group.getPreference(i);
        if((KEY_MANUAL_GUIDE.equals(preference.getKey())||KEY_MANUAL_GUIDE_CATEGORYequals(preference.getKey())...)){
            preference.setVisible(false);        
        }
        if(!DevelopmentSettingsEnabler.isDevelopmentSettingsEnable(requireActivity())&&
        "developer_mode_category".equals(preference.getKey())){
            preference.setVisible(false);
            continue;        
        }
        if(preference instanceof PreferenceGroup){
            visibleCount+=getVisivlePreferenceCount((PreferenceGroup)preference);        
        }else if (preference.isVisible()){
            visibleCount++;        
        }    
    }
    return visibleCount;
}

视频模式的环绕声默认为近场,与预期结果不符

初次进入DTS,或重置DTS模式时,并非为进场,与预期不符

判断该BUG为功能类BUG,由于观察到本项目有正确的默认值,所以判断和逻辑代码有关(判断进行设置值),于是我们进行BUG检索发现xxxx有类似的BUG,我们观察修改链接可以看到DTS的相关源代码(本项目没有该源码)

java 复制代码
public class DtsDefualtSettings{
    private boolean mDoubleSpeaker;
    private boolean isDoubleSpeaker(){
        mDoubleSpeaker="1".equals(Settings.Global.getString(mContext.getContentResolver(),"xxx_dual_mic_support"));
        Utils.logd(TAG,"isDoubleSpeaker="+mDoubleSpeaker);
        return mDoubleSpeaker;    
    }
}//可以看到通过Settings.Global xxx_dual_mic_support来判断是否为双声道项目
java 复制代码
//检索framework发现并没有定义xxx_dual_mic_support对应的属性
/base/servuces/core/java/com/android/server/audio/AudioService
private static final boolean XXX_DUAL_MIC_SUPPORT="1".equals(SystemProperties.get("ro.vendor.xxx_dual_mic_support","false"));
if(XXX_DUAL_MIC_SUPPORT){
    Settings.Global.putString(mContext.getContentResolver(),"xxx_dual_mic_support",1);
}else{
    Settings.Global.putString(mContext.getContentResolver(),"xxx_dual_mic_support",0);
}

所以解决办法就是添加宏控 vice/xxx/product_parts/device_sdd.mk

java 复制代码
ifeq($(strip$(XXX_DUAL_MIC_SUPPORT)),yes)
    PRODUCT_PRODUCT_PROPERTIES+=ro.vendor.xxx_dual_mic_support=1    
endif



device/xxx/product/xxxxxxx/ProductConfig_SDD.mk

XXX_DUAL_MIC_SUPPORT = yes

合入沙特国家需求

简单来说:需要在设置中显示认证信息菜单以及提供的认证号 所以可以知道 这类菜单一定是有相关判断逻辑与开关,也有相关位置存放认证号,从BUG详情中我们看到了认证号

根据我们的设置问题分析步骤,仅从标题就可判断此BUG为需求类BUG,所以其他项目大概率是有该需求。于是我们查询上一项目:其他项目找到了类似的问题可以提供思路。(后续发现修改并不完全一致)例如:从其他项目我们大致确定了该界面的逻辑代码位置 Settings/src_xxx/com/xxxxxx/aboutphone/CertigiedInfoActivity.java 让我们看看关键代码

java 复制代码
String model=getShortModel();//获取品牌名称(截取后的)例如xxxx
mCkView=(LinearLayout)findViewById(R.id.xxxx_ckd_ll);
boolean isBrazil=TsUtils.equals(TsUtils.getCountryCode,CertigiedInfoPreferenceController.COUNTRY_CODE_BR);
//CertigiedInfoPreferenceController也是涉及到的一个类
boolean isSupportDoc =CertifiedInfoActivity.isSupportDoc(mResources,model);
mDocView.setVisibility((!isSupportDoc||FeatureOption.XXX_DOC_NOT_SUPPORT||isBrazil)?View.GONE:VIEW.VISIBLE);
boolean isCitcSupport=isSupportCitc(mResources,model);//检索品牌名称是否在资源文件中,接下来我们看一下isSupportCitc方法,便可以知道需要认证的项目存放在哪个资源文件
boolean isSa=TsUtils.equals(TsUtils.getCountryCode(),CertigiedInfoPreferenceController.COUNTRY_CODE_SA);
mCitcView.setVisibility(isCitcSupport&&isSa?View.VISIBLE:View.GONE);
java 复制代码
public static boolean isSupportCitc(Resource res,String model){
    if(TextUtils.isEmpty(model)){
        reutrn false;    
    }
    model=model.getLowerCase();
    List<String> citcProjectsList=null;
    try{
        citcProjectsList=Arrays.asList(res.getStringArray(res.getIdentifier("xxx_citc_projects_support","array",mCertifiedResPkg)));//我们看到了获取xxx_citc_projects_support列表
    }catch(NotFoundException e ){
        return false;    
    }
    if(citcProjectList==null||!citcpRojectsList.contains(model)){
        return false;    
    }
    return ture;
}

所以,我们确定了资源文件以及资源id:xxx_citc_projects_support,

可以直接进行命令搜索该资源文件,并添加项目名称 为了确保万无一失,使用adb查找ro.product.model属性确定名称

<string-array name="xxx_citc_projects_support" translatable="false">

<item>项目名</item> ... <item>项目名</item>

</string-array> 并添加认证号 t0_sys/device/xxx/product/xxx/ProductConfig/vendor/prjconfig/overlay/vendor/xxx.../app/XXXSettingsApk/res_app/values/certified_strings.xml

设置认证码,此处为overlay Setting 如果只是在原生(客制化)Setting中设置认证码会被这里覆盖

<string name="xxx_citc_sign">"(TA xxxxxxx)"</string>

偶现铃声设置为空

现象:手机格式化\重置,到设置-声音与振动中观察,期望结果是默认铃声为A、通知提示音为B,但是偶现默认铃声与通知提示音都为无

此问题涉及公司机密,相关信息与代码脱敏后另写一篇

相关推荐
艾莉丝努力练剑31 分钟前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
人生游戏牛马NPC1号2 小时前
学习 Flutter (三):玩安卓项目实战 - 上
android·学习·flutter
小馬佩德罗4 小时前
Android系统的问题分析笔记 - Android上的调试方式 debuggerd
android·调试
清霜之辰5 小时前
安卓基于 FirebaseAuth 实现 google 登录
android·google·auth·firebase
GitLqr5 小时前
数码洞察 | Apple VS DMA、三星新品、Android 16KB Page Size
android·ios·samsung
alexhilton5 小时前
SnapshotFlow还是collectAsState?对于Jetpack Compose来说哪个更香?
android·kotlin·android jetpack
没有羊的王K5 小时前
SSM框架学习——day1
java·学习
Erwooow6 小时前
Android 16k jni修改
android
l软件定制开发工作室7 小时前
基于Android的景点旅游信息系统App
android
张可7 小时前
一个KMP/CMP项目的组织结构和集成方式
android·前端·kotlin