• 全新单提交:清除含敏感信息的旧历史(sudo 口令、内网 IP、SSH 密钥路径、热点 SSID、设备 MAC) • 本地开发文档/测试记录/构建脚本全部移入 gitignored 的 devdocs/ 与 scripts/build/(不入库) • 保留:MeowOS 源码(launcher/watchdog/bootmenu/meow_svcd/SDK)、项目规范文档、mips-repo 增补组件:SDK 统一日志+通知 API、meow_svcd 服务管理器、mips-repo 软件仓库
133 lines
5.8 KiB
Bash
Executable File
133 lines
5.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# verify_apps.sh — R3 Pro II 应用加载器真机全链路验证编排
|
|
#
|
|
# 用法:
|
|
# ./verify_apps.sh stab 稳定性检查(60s 单实例无 recovery_all)
|
|
# ./verify_apps.sh nav QOBUZ 触摸注入导航流媒体页->Qobuz(应用列表页)
|
|
# ./verify_apps.sh shot <name> fb0 截图存 device_test/<name>.png(+ascii)
|
|
# ./verify_apps.sh tap <x> <y> goodix 触摸注入(坐标按设备 abs 缩放)
|
|
# ./verify_apps.sh scen <n> 布置 TF 卡场景 n (0..5, 见下)
|
|
# ./verify_apps.sh exitapp 让 hello 退出(注入任意键)
|
|
# ./verify_apps.sh wdtap 点击看门狗虚拟返回键(20,20)
|
|
# ./verify_apps.sh loop <n> 重复 n 次 列表->启动->返回键退出
|
|
# ./verify_apps.sh devinfo 输入设备 abs 范围等调试信息
|
|
#
|
|
# 场景:
|
|
# scen 0 正常: MeowAPPs/hello/(hello + app.json 有效)
|
|
# scen 1 无卡: umount sd_0 (测试后必须 scen 0 恢复)
|
|
# scen 2 无 MeowAPPs 目录
|
|
# scen 3 MeowAPPs 空目录
|
|
# scen 4 坏 app.json(缺 exec 字段, 应跳过)
|
|
# scen 5 exec 不存在(点击应提示无法启动)
|
|
set -u
|
|
DEV="<alt_device_ip>"
|
|
KEY="$HOME/Project/R3ProII/ssh_keys/<device_key>"
|
|
SSH="ssh -i $KEY -o StrictHostKeyChecking=accept-new -o ConnectTimeout=8"
|
|
ROOT=~/Project/R3ProII
|
|
TAP=$ROOT/patch_v2/uinput_tap/uinput_tap
|
|
SD=/usr/data/mnt/sd_0
|
|
|
|
s() { timeout 40 $SSH root@$DEV "$1"; }
|
|
|
|
devinfo() {
|
|
echo "== input devices =="
|
|
s 'for d in /sys/class/input/event*/device; do [ -f $d/name ] && echo "event$(basename $(dirname $d)|cut -c6-) $(cat $d/name)"; done 2>/dev/null'
|
|
s 'cat /proc/bus/input/devices | grep -A6 -E "goodix|Name=" | head -50'
|
|
}
|
|
|
|
# 触摸注入: 自动按 goodix abs 范围把屏幕坐标(480x720)换算成设备坐标
|
|
tap() {
|
|
local sx=$1 sy=$2
|
|
# 从 /proc/bus/input/devices 解析 goodix 的 ABS_MT_POSITION_X/Y(优先) 或 ABS_X/Y 的 max
|
|
local devinfo=$(s 'cat /proc/bus/input/devices')
|
|
local maxx maxy
|
|
maxx=$(echo "$devinfo" | awk '/Name="goodix/{f=1} f&&/ABS_MT_POSITION_X|ABS_X/{for(i=1;i<=NF;i++){gsub(/,/,"",$i); if($i ~ /^[0-9]+$/ && $i+0>m) m=$i+0}} END{print m}')
|
|
maxy=$(echo "$devinfo" | awk '/Name="goodix/{f=1} f&&/ABS_MT_POSITION_Y|ABS_Y/{for(i=1;i<=NF;i++){gsub(/,/,"",$i); if($i ~ /^[0-9]+$/ && $i+0>m) m=$i+0}} END{print m}')
|
|
[ -z "$maxx" ] || [ "$maxx" = "0" ] && maxx=767
|
|
[ -z "$maxy" ] || [ "$maxy" = "0" ] && maxy=1279
|
|
local dx=$(( sx * maxx / 480 ))
|
|
local dy=$(( sy * maxy / 720 ))
|
|
echo "tap screen($sx,$sy) -> dev($dx,$dy) max($maxx,$maxy)"
|
|
s "/data/uinput_tap inject $dx $dy /dev/input/event1"
|
|
}
|
|
|
|
stab() {
|
|
echo "== 60s 稳定性检查 =="
|
|
sleep 60
|
|
s 'echo "instances=$(ps | grep hiby_player | grep -v grep | grep -v sh | wc -l)"; ps | grep hiby_player | grep -v grep | grep -v sh; ls /data/recovery_all 2>/dev/null && echo FLAG || echo no_flag'
|
|
}
|
|
|
|
shot() {
|
|
local name=${1:-shot}
|
|
s 'dd if=/dev/fb0 of=/data/x.raw bs=691200 count=1 2>/dev/null'
|
|
timeout 30 $SSH root@$DEV "cat /data/x.raw" > $ROOT/device_test/$name.raw
|
|
python3 $ROOT/device_test/fb2png.py $ROOT/device_test/$name.raw $ROOT/device_test/$name.png >/dev/null 2>&1
|
|
# 判定色深并生成 ascii
|
|
local sz=$(stat -c%s $ROOT/device_test/$name.raw)
|
|
if [ "$sz" = "691200" ]; then
|
|
python3 $ROOT/device_test/ascii_fb.py $ROOT/device_test/$name.raw 96 40 > $ROOT/device_test/$name.txt
|
|
else
|
|
echo "unexpected raw size $sz"
|
|
fi
|
|
echo "saved $ROOT/device_test/$name.png (raw $sz)"
|
|
}
|
|
|
|
nav() {
|
|
# nav: 假设当前在流媒体页; 注入 Qobuz 入口点击
|
|
tap 355 95
|
|
sleep 2
|
|
}
|
|
|
|
exitapp() {
|
|
# 注入一个任意键事件让 hello 退出 (VOLUMEUP 键事件直接写 event1)
|
|
s "/data/uinput_tap key 115" 2>/dev/null || \
|
|
s "printf '\x01\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > /dev/input/event1" 2>/dev/null || \
|
|
echo "key inject failed, fallback: send SIGTERM via watchdog tap"
|
|
}
|
|
|
|
wdtap() {
|
|
tap 20 20
|
|
sleep 2
|
|
}
|
|
|
|
scen() {
|
|
local n=${1:-0}
|
|
case $n in
|
|
0) s "mkdir -p $SD/MeowAPPs/hello; cp -f /data/hello.bin $SD/MeowAPPs/hello/hello; cp -f /data/hello_app.json $SD/MeowAPPs/hello/app.json; chmod 755 $SD/MeowAPPs/hello/hello; ls $SD/MeowAPPs/hello/; echo SCEN0_OK" ;;
|
|
1) s "umount $SD 2>/dev/null || umount /usr/data/mnt/sd_0 2>/dev/null; grep sd_0 /proc/mounts || echo SCEN1_NOCARD_OK" ;;
|
|
2) s "mv $SD/MeowAPPs $SD/MeowAPPs.bak 2>/dev/null; ls $SD/ 2>/dev/null; echo SCEN2_NODIR_OK" ;;
|
|
3) s "mkdir -p $SD/MeowAPPs; ls -la $SD/MeowAPPs/; echo SCEN3_EMPTY_OK" ;;
|
|
4) s "mkdir -p $SD/MeowAPPs/hello $SD/MeowAPPs/bad; cp -f /data/hello.bin $SD/MeowAPPs/hello/hello; cp -f /data/hello_app.json $SD/MeowAPPs/hello/app.json; chmod 755 $SD/MeowAPPs/hello/hello; echo '{\"name\":\"Bad App\"}' > $SD/MeowAPPs/bad/app.json; cat $SD/MeowAPPs/bad/app.json; echo SCEN4_BADJSON_OK" ;;
|
|
5) s "mkdir -p $SD/MeowAPPs/hello $SD/MeowAPPs/nonexec; cp -f /data/hello.bin $SD/MeowAPPs/hello/hello; cp -f /data/hello_app.json $SD/MeowAPPs/hello/app.json; chmod 755 $SD/MeowAPPs/hello/hello; echo '{\"name\":\"Ghost App\",\"exec\":\"/usr/data/mnt/sd_0/MeowAPPs/nonexec/nope\"}' > $SD/MeowAPPs/nonexec/app.json; cat $SD/MeowAPPs/nonexec/app.json; echo SCEN5_NOEXEC_OK" ;;
|
|
*) echo "usage: scen 0..5"; return 1 ;;
|
|
esac
|
|
}
|
|
|
|
loop() {
|
|
local n=${1:-3}
|
|
for i in $(seq 1 $n); do
|
|
echo "== loop $i =="
|
|
nav
|
|
shot loop_${i}_list
|
|
tap 240 112 # 第 0 行 (hello)
|
|
sleep 3
|
|
shot loop_${i}_app
|
|
wdtap # 看门狗返回键
|
|
sleep 2
|
|
shot loop_${i}_back
|
|
done
|
|
}
|
|
|
|
case "${1:-}" in
|
|
stab) stab ;;
|
|
nav) nav ;;
|
|
shot) shot "${2:-shot}" ;;
|
|
tap) tap "${2:-0}" "${3:-0}" ;;
|
|
scen) scen "${2:-0}" ;;
|
|
exitapp) exitapp ;;
|
|
wdtap) wdtap ;;
|
|
loop) loop "${2:-3}" ;;
|
|
devinfo) devinfo ;;
|
|
*) echo "usage: $0 stab|nav|shot [name]|tap x y|scen 0..5|exitapp|wdtap|loop [n]|devinfo"; exit 1 ;;
|
|
esac
|