后台驻留专项工具
来源:飞书 docx(obj_token: Xb85dhTCSoQArtxxfAOcDS9anhc)
注:文档内联图片为飞书内部 stream 鉴权链接(无独立 file_token,无法离线转存),已保留文字描述。3 个附件(apk / setprop 脚本 / hidumper 输出)已下载到本地
attachments/子目录。
📌 当前旧框架工具已不再维护,请使用新框架工具:性能全场景测试工具用户使用指南
测试前预置条件以及结果说明与本文档一致
注意事项
注意:测试步骤7抖音 & 抖音极速版新增预置操作
注意:国际机器和竞品机系统应用可能需要适配,先测试一轮加第二轮一个应用 python3 bg_alive_special_test.py -num 56 确认结果;(4G及以下31,6-8G:37,8G以上56),保证 pid 列不能出现 None
📷 图片描述: “Search Results” 窗口,列出 Sheet/Cell/Content 等信息,其中”启动记录 pid”列有多个 None 标识。(token
internal-stream,无独立 file_token,飞书内部鉴权链接无法离线转存)
一、工具地址
内部
代码拉取:git clone git@git.n.xiaomi.com:zs15/FluenctTest.git,没有权限联系 @王晨羽
网址:https://git.n.xiaomi.com/zs15/FluenctTest
拉取失败先配置 ssh key 参考,邮箱改为自己邮箱:git命令汇总.pptx
每次测试前先更新一下:git pull
外部封装(同流畅度工具)
名称:package_new
🔗 小米企业网盘外链:地址 | 密码
777E
二、测试步骤
-
单轮次(4G及以下30;6-8G:36;8G以上55)
-
注意原神、崩坏3、开心消消乐请在浏览器官网下载;官网和应用商店存在差异;
- 其中,开心消消乐输入下面命令确保可以正常启动
adb shell am start com.happyelements.AndroidAnimal/com.happyelements.hellolua.MainActivity-
预置条件:全部启动一次并点掉弹框进入主页面,游戏资源加载完成,应用UI操作见用例表格中应用执行动作;
-
填充照片、联系人、通话记录、短信各4000;4个天气、本地录制31-39s的视频;
📎 附件:fill_data.apk(数据填充应用,原 token
XiWfbu7AeoMnyUxX2tccDeLCnNe,~20MB) -
账号需要登录:微信(test好友视频确定可以正常通话,设置好友名为test置顶)、小红书、钉钉(进test群)、拼多多、支付宝、淘宝、QQ、抖音;
📷 图片描述: 账号登录态截图(微信 / 小红书 / 钉钉等)。(token
internal-stream,无独立 file_token)
-
抖音 & 抖音极速版:我->设置->播放设置->后台展示音频播放组件(关闭)。
-
查看日志等待编译结束:
adb logcat | grep -e "/apex/com.android.art/bin/dex2oat" -e "dex2oat took"查看编译日志,日志停留在 “dex2oat took 479.083ms” 这种日志并不再刷新,并且后台没有 dex2oat 的进程:adb shell ps -A | grep dex2oat -
温度查询:
adb shell dumpsys battery | grep temperature -
atx软件省电管理设置为不限制;
vivo:atx长按-》电量-》后天耗电管理-》允许后台高耗电;
-
预置开关打开
10.1 高通/MTK平台打开方式:
adb shell setprop persist.sys.miui.cameraopt.debug true
adb shell setprop persist.sys.miui.camera.boost.debug true
adb shell setprop persist.sys.gz.disablethaw true
adb reboot
等待重启结束之后开始测试;10.2 玄界平台打开方式:
📎 附件:xuanjie_setprop.sh(玄界平台 setprop 预置脚本,原 token
PnYsbTr6SonTN5xxze9cUXIln5r)
-
执行(预计执行时间6H,内存占用8G)国内:国际:
-
封装:
./bg_alive_special_test -s 设备号 -
源码:
python3 bg_alive_special_test.py -s 设备号- 鸿蒙next系统(适配进行中):
python3 bg_alive_special_test.py -s 设备号 -hm yes
- 鸿蒙next系统(适配进行中):
-
封装:
./bg_alive_special_test -r gl -ui false -s 设备号 -
源码:
python3 bg_alive_special_test.py -r gl -ui false -s 设备号
-
-
看到应用启动ui操作执行成功
避免出现如下日志:
📷 图片描述: 执行测试时出现的错误日志(2024-09-16 19:28:02),包含 “bg_alive_special_test.py:1038 =============wrong============” 以及 “get_app_ui Exception str The file lock ‘/home/-test/.uiautomator2/filelocks/OGVizDZLMMmE=.lock’ could not be acquired.” 文件锁获取失败。(token
internal-stream,无独立 file_token)
如果出现,执行
python3 -m uiautomator2 init
ATX的省点模式改成无限制三、相关调试参数说明
-num:应用执行总个数,不指定默认500;
例如:python3 bg_alive_special_test.py -num 10;
一轮对应个数:(4G及以下30;6-8G:36;8G以上55)
-s 设备号
-ui:默认不需要指定,如果不进行ui操作:-ui false;
-p:默认为no,选择['yes', 'no'],默认不抓取trace也不分析trace信息;
-repare:默认no,执行命令增加-repare yes支持所有待测应用的预启动默认15s,可以手动执行点弹窗操作;
-un_camera: 取消相机和微信视频通话,是后加yes
-r 地区,cn/gl,默认cn,测试国际应用:python3 bg_alive_special_test.py -r gl;
-hm, yes、no,默认no,是否是鸿蒙next系统
四、异常处理
- 测试时间不符合预期,过长或者ui操作不成功;
问题:出现类似报错:get_app_ui Exception str The file lock '/home/mi/.uiautomator2/filelocks/MTBBRTRYMEQ4WTAwMFNa.lock' could not be acquired.
解决:打开atx再运行查看清后台是否成功,省电策略改成无限制;
📷 图片描述: 后台驻留专项工具运行日志,第11行红色高亮显示 “get_app_ui Exception str The file lock ‘/home/mi/.uiautomator2/filelocks/MTBBRTRYMEQ4WTAwMFNa.lock’ could not be acquired.”,时钟场景主页滑动 UI 操作获取应用 UI 时文件锁获取失败。(token
internal-stream,无独立 file_token)
- ui未执行成功,初始化UIautomator
卸载atx,并执行
python3 -m uiautomator2 init打开atx点击启动uiautomator
五、结果展示
- 应用存活网页版详情,见 live_detail.html
📷 图片描述: 后台驻留专项工具测试结果相关文件清单,包含 meminfo、trace、bg_alive.json、bg_log_20240307-202834.txt、bg_log_select.txt、bugreport-zeus-UKQ1.23…、exit_process_info、log、num.png、phone_info、pkg_info.txt、result.xlsx 等。(token
internal-stream,无独立 file_token)
- 应用数量详情页面
最大值、最小值、平均值(下拉到底能看到见下图):从第二轮开始统计的存活数量;
比如:第二轮 4G及以下从31个应用开始(6-8G:37,8G以上56)
增加相机拟合数据,由于相机会导致驻留个数迅速下降,会选取上一个应用对应的存活数量下拉到相同数值,对应的最大最小值统计原理同上;
📷 图片描述: “第二次复测 - 关闭相机相关log - 后台驻留验证” 应用数量详情,列出前五/四/三/二/一个的存活率及最大/最小/平均值,相机拟合对应值(22、13、16.96)被红色框突出。(token
internal-stream,无独立 file_token)
📷 图片描述: 应用数量详情页面,包含应用名称、存活数量、被杀数量等信息,应用名称有”时钟""微信""等。(token
internal-stream,无独立 file_token)
📷 图片描述: 应用数量详情页面,应用存活网页版详情。表格含应用名称、版本号、冷启动/温启动/热启动(0/1/2)、存活数量(1=存活),右下角计数 445、求和 52288、平均 11.773033708。(token
internal-stream,无独立 file_token)
- 应用状态及驻留结果详情
对角线为启动状态,0是冷启动、1是温启动、2是热启动;其余为存活状态,1代表存活;
驻留为启动应用执行ui后,退出到桌面之前的驻留情况;
存活数量与存活状态的对应关系:所有为1状态的应用个数和(不能直接计算每行1的个数);有部分应用多次存活,应该识别1对应的应用然后去重;
📷 图片描述: 应用数量详情页面,包含应用名称、场次、时钟、微信、日历等多列数据,以 0/1 标识应用状态。(token
internal-stream,无独立 file_token)
前第五个驻留概率计算方法:
500个应用分别计算前五个对应的驻留率,最终结果=相加之后/500,前1-5驻留率方法相同;
第一个应用驻留率默认100%;
比如在第四个应用前三个驻留率和前五驻留率相同,皆为前三个的个数相加/3;
📷 图片描述: 后台驻留专项工具相关代码界面,包含
alive_prog_five_list.append等列表操作和print(alive_prog_five_list)打印语句,下方为大量数字数据输出。(tokeninternal-stream,无独立 file_token)
六、新增需求
- 应用执行取消相机和微信视频通话
-un_camera: 取消相机和微信视频通话,是后加yes
举例:
python3 bg_alive_special_test.py -un_camera yes七、原理说明
- 应用启动 & 冷热启动判断方法:
根据 am start-activity -W -n activity 返回的 state 信息;
- 启动时pid获取
if pkg == 'in.amazon.mShop.android.shopping':
res = self.shell(f"ps -A | grep '{pkg}'")
LOG.info(f'当前应用名为:{pkg},res值为:{res}')
else:
res = self.shell(f"ps -A | grep '{pkg}$'\")
if res:
return res.split()[1]
else:
return None- 驻留判断方法:(必须)
dumpsys meminfo 信息,原始数据储存在 txt 文件中
检测 Total PSS by process: 中包名 pid 信息表示应用为存活状态;
#20240827调整为不包含activities也算存活
- 获取log数据,通过正则匹配储存到 bg_log_时间.txt 文件中
self.popen = Popen(["adb", "-s", self.d, "logcat", "-b", "events", "-T", start_time + ".000", "-s",
"am_proc_start", "wm_create_activity", "wm_activity_launch_time", "wm_stop_activity",
"wm_resume_activity", "am_kill", "killinfo", "am_proc_died", "wm_on_start_called",
"wm_on_top_resumed_gained_called"], bufsize=1, stdout=self.bg_log)
1. AMS杀进程
am_kill_re = re.compile(r'.*am_kill : \[\d+,(?P<pid>\d+),(?P<package>.*?),\d+,(?P<reason>.*)]')
2. LMK杀进程
killinfo_re = re.compile(r".*killinfo: \[(?P<pid>\d+),(?P<package>.*?),.*")
3. 进程结束日志
am_proc_died_re = re.compile(r'.*am_proc_died: \[\d+,(?P<pid>\d+),(?P<package>.*?),.*')- bg_log_时间.txt 文件中工具用到的内容会单独保存至 bg_log_kill_select.txt 文件中;
- 获取被杀原因,exit_info 信息
1. 获取
通过 adb -s {self.d} shell dumpsys activity exit-info {package} 获取
2. 存取:exit_process_info 文件- trace分析部分,如果需要 -p yes(可选,非必须)
1. 启动时长:select dur from android_startups 获取启动时长和firstactivity时长
2. mm_vmscan_direct_reclaim耗时及调用线程(utid)
DR次数、DR耗时(ms)、DR次数(top)、DR耗时(top)(ms)获取
SELECT dur, utid FROM slice JOIN thread_track ON thread_track.id = slice.track_id WHERE slice.name = 'mm_vmscan_direct_reclaim'
3. kswapd次数、kswapd耗时(ms)
状态以'S'结束的次数
SELECT dur, end_state FROM sched_slice join thread on sched_slice.utid = thread.utid where thread.name = 'kswapd0'
下面数据(每条log对应一个page,每个page大小为4k)
4. filemap_add信息:(filemap_add(M)、filemap_add(top)(M)、
select count(id) as count_number, utid from raw where name =
'mm_filemap_add_to_page_cache' group by utid
5. filemap_delete(M)、filemap_delete(top)(M)
select count(id) as count_number, utid from raw where name =
'mm_filemap_delete_from_page_cache' group by utid
6. blockTotal(ms)、blockTotal(UI)(ms)待更新- kswapd0
📷 图片描述: 鸿蒙next系统中 kswapd0 进程的 CPU 调度切片信息。上方 CPU 频率(Cpu 6/7 均 5GHz),下方 CPU 调度切片详情:Process/Thread 为 kswapd0[84],Cmdline kswapd0,Start time 1664305477216,Duration 6146,Prio 120,End State Sleeping。(token
internal-stream,无独立 file_token)
鸿蒙后台驻留工具原理说明(开发中)
八、鸿蒙next系统原理说明
- 应用启动
hdc shell aa start -a {abilityName} -b {bundleName}
例如:aa start -a EntryAbility -b com.taobao.idlefish4ohos
aa dump -l # 获取(app state #FOREGROUND 查看当前任务栈的ability信息)- pid获取
aa dump -r
或者
ps -ef | grep com.taobao.idlefish4ohos
self.shell(f"ps -ef | grep '{package}$'")-
获取数据
hidumper -c; -
检测
Total PSS by OOM adjustment中包名 pid 信息表示应用为存活状态;📎 附件:hidumper_output.txt(hidumper -c 输出样例,原 token
XwcXbPscuoFccWxUesTcis9xnHk,~796KB) -
其他:
- 获取应用详情:
bm dump -n com.kuaishou.hmapp
- 获取应用详情:
-
相关参考文档:
hidumper:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/hidumper-V5
hdc相关命令:https://blog.csdn.net/ToBeTheEnder/article/details/139325200
九、自动化流程
根据 国内-应用驻留用例 中的执行顺序和ui操作,按顺序循环执行,直到 num 指定数量完成;
十、工具适配
activity适配
报错信息为当前应用 activity 存在异常,请联系开发者适配!!!
📷 图片描述: Linux 终端 Fluency Test Package 20250919 后台驻留专项工具运行日志,启动第 2 个应用 LINE:jp.naver.line.android 时因 launch activity 引发 Exception,提示当前应用 activity 存在异常。(token
internal-stream,无独立 file_token)
- 查询activity,方法如下
📷 图片描述: Linux 终端执行
adb shell dumpsys window | grep mCurrentFocus等指令,mCurrentFocus 指向 jp.naver.line.android 包下 com.linecorp.line.registration.ui.RegistrationActivity。(tokeninternal-stream,无独立 file_token)
- 找到文件 app_info.json;
- 找到对应的应用,将 main_activity 修改为合适的 activity
📷 图片描述: 代码编辑器 app_info.json 文件中的 “LINE” 部分,main_activity 被红色框标注,值为 jp.never.line.android/com.linecorp.registration.ui.RegistrationActivity。(token
internal-stream,无独立 file_token)