后台驻留专项工具

来源飞书 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

二、测试步骤

  1. 安装指定应用,国内应用列表见 国内-应用驻留用例外部)应用执行顺序,国际应用列表见 国际、印度应用驻留外部);

  2. 单轮次(4G及以下30;6-8G:36;8G以上55)

  3. 注意原神、崩坏3、开心消消乐请在浏览器官网下载;官网和应用商店存在差异;

    1. 其中,开心消消乐输入下面命令确保可以正常启动
adb shell am start com.happyelements.AndroidAnimal/com.happyelements.hellolua.MainActivity
  1. 预置条件:全部启动一次并点掉弹框进入主页面,游戏资源加载完成,应用UI操作见用例表格中应用执行动作;

  2. 填充照片、联系人、通话记录、短信各4000;4个天气、本地录制31-39s的视频;

    📎 附件fill_data.apk(数据填充应用,原 token XiWfbu7AeoMnyUxX2tccDeLCnNe,~20MB)

  3. 账号需要登录:微信(test好友视频确定可以正常通话,设置好友名为test置顶)、小红书、钉钉(进test群)、拼多多、支付宝、淘宝、QQ、抖音;

📷 图片描述: 账号登录态截图(微信 / 小红书 / 钉钉等)。(token internal-stream,无独立 file_token)

  1. 抖音 & 抖音极速版:我->设置->播放设置->后台展示音频播放组件(关闭)。

  2. 查看日志等待编译结束:adb logcat | grep -e "/apex/com.android.art/bin/dex2oat" -e "dex2oat took" 查看编译日志,日志停留在 “dex2oat took 479.083ms” 这种日志并不再刷新,并且后台没有 dex2oat 的进程:adb shell ps -A | grep dex2oat

  3. 温度查询:

    adb shell dumpsys battery | grep temperature
  4. atx软件省电管理设置为不限制;

    vivo:atx长按-》电量-》后天耗电管理-》允许后台高耗电;

  5. 预置开关打开

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

  1. 执行(预计执行时间6H,内存占用8G)国内国际

    1. 封装:./bg_alive_special_test -s 设备号

    2. 源码:python3 bg_alive_special_test.py -s 设备号

      1. 鸿蒙next系统(适配进行中):python3 bg_alive_special_test.py -s 设备号 -hm yes
    3. 封装:./bg_alive_special_test -r gl -ui false -s 设备号

    4. 源码:python3 bg_alive_special_test.py -r gl -ui false -s 设备号

  2. 看到应用启动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系统

四、异常处理

  1. 测试时间不符合预期,过长或者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)

  1. ui未执行成功,初始化UIautomator

卸载atx,并执行

python3 -m uiautomator2 init

打开atx点击启动uiautomator

五、结果展示

  1. 应用存活网页版详情,见 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)

  1. 应用数量详情页面

最大值、最小值、平均值(下拉到底能看到见下图):从第二轮开始统计的存活数量;

比如:第二轮 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)

  1. 应用状态及驻留结果详情

对角线为启动状态,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) 打印语句,下方为大量数字数据输出。(token internal-stream,无独立 file_token)

六、新增需求

  1. 应用执行取消相机和微信视频通话
-un_camera: 取消相机和微信视频通话,是后加yes
举例:
python3 bg_alive_special_test.py -un_camera yes

七、原理说明

  1. 应用启动 & 冷热启动判断方法:

根据 am start-activity -W -n activity 返回的 state 信息;

  1. 启动时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
  1. 驻留判断方法:(必须)

dumpsys meminfo 信息,原始数据储存在 txt 文件中

检测 Total PSS by process: 中包名 pid 信息表示应用为存活状态;

#20240827调整为不包含activities也算存活

  1. 获取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>.*?),.*')
  1. bg_log_时间.txt 文件中工具用到的内容会单独保存至 bg_log_kill_select.txt 文件中;
  2. 获取被杀原因,exit_info 信息
1. 获取
通过 adb -s {self.d} shell dumpsys activity exit-info {package} 获取
2. 存取:exit_process_info 文件
  1. 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系统原理说明

  1. 应用启动
 hdc shell aa start -a {abilityName} -b {bundleName}
 例如:aa start -a EntryAbility -b com.taobao.idlefish4ohos
 
 aa dump -l # 获取(app state #FOREGROUND 查看当前任务栈的ability信息)
  1. pid获取
aa dump -r
或者
ps -ef | grep com.taobao.idlefish4ohos
self.shell(f"ps -ef | grep '{package}$'")
  1. 获取数据 hidumper -c

  2. 检测 Total PSS by OOM adjustment 中包名 pid 信息表示应用为存活状态;

    📎 附件hidumper_output.txt(hidumper -c 输出样例,原 token XwcXbPscuoFccWxUesTcis9xnHk,~796KB)

  3. 其他:

    1. 获取应用详情:bm dump -n com.kuaishou.hmapp
  4. 相关参考文档:

hidumper:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/hidumper-V5

aa相关命令:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/aa-tool-V5#%E5%90%AF%E5%8A%A8%E5%91%BD%E4%BB%A4start

hdc相关命令:https://blog.csdn.net/ToBeTheEnder/article/details/139325200

内存峰值占用:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/ide-peak-dynamic-memory-usage-0417-V13

九、自动化流程

根据 国内-应用驻留用例 中的执行顺序和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。(token internal-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)