Files

137 lines
6.3 KiB
Bash
Executable File

#!/bin/bash
# verify_chain.sh — MeowAPPs 全链路真机验证编排(第五轮)
# 用法: ./verify_chain.sh <step>
# check|deploy|stable|wake|launcher|stream|apps|back|clean|status
# 安全纪律: 数 PID 实例、先杀 hiby_player.sh 再杀 hiby_player、绝不 killall、
# 重启前 rm /data/recovery_all、发现 recovery_all 立即告警
set -u
DEV="<alt_device_ip>"
KEY="$HOME/Project/R3ProII/ssh_keys/<device_key>"
PATCH="$HOME/Project/R3ProII/patch_v2/hiby_player_patched_v2"
WD="$HOME/Project/R3ProII/patch_v2/meow_watchdog/meow_watchdog"
HELLO="$HOME/Project/R3ProII/patch_v2/apps_assets/apps/os.meow.hello/hello"
HJ="$HOME/Project/R3ProII/patch_v2/apps_assets/apps/os.meow.hello/app.json"
TAP="$HOME/Project/R3ProII/patch_v2/uinput_tap/uinput_tap"
KEYTAP=/data/keytap
ASSETS="$HOME/Project/R3ProII/patch_v2/apps_assets"
SHOTDIR="$HOME/Project/R3ProII/device_test"
SSH="ssh -i $KEY -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10"
s() { timeout 30 $SSH root@$DEV "$1" 2>&1 | grep -vE "post-quantum|store now|upgraded|openssh.com"; }
count_inst() { s 'ps | grep hiby_player | grep -v grep | grep -v sh | wc -l'; }
check() {
echo "== device state =="
s 'echo "uptime=$(awk "{print \$1}" /proc/uptime)"; ps | grep -E "hiby|gdbserver" | grep -v grep'
s 'ls /data/recovery_all 2>/dev/null && echo FLAG_EXISTS || echo no_flag'
s 'mount | grep -cE "on /usr/(bin/hiby_player|resource/layout/theme1)"'
s 'cat /sys/class/backlight/backlight_pwm0/brightness 2>/dev/null'
s 'md5sum /usr/bin/hiby_player | cut -c1-8'
}
deploy() {
echo "== push =="
timeout 60 $SSH root@$DEV "cat > /data/hiby_player_patched_v2" < "$PATCH" || return 1
timeout 60 $SSH root@$DEV "cat > /usr/data/meow_watchdog" < "$WD" || return 1
timeout 60 $SSH root@$DEV "cat > /data/uinput_tap" < "$TAP" || return 1
timeout 30 $SSH root@$DEV "cat > /data/keytap" < "$KEYTAP" 2>/dev/null || true
s 'chmod 755 /data/hiby_player_patched_v2 /usr/data/meow_watchdog /data/uinput_tap /data/keytap'
s 'md5sum /data/hiby_player_patched_v2 | cut -c1-8'
echo "== 设备侧组装 =="
s 'if ! grep -q "sd_0" /proc/mounts; then mount /dev/mmcblk0p1 /usr/data/mnt/sd_0 2>/dev/null || echo mount_fail; fi
mkdir -p /usr/data/mnt/sd_0/MeowAPPs/os.meow.hello /data/overlay
cp -f /data/hello.bin /usr/data/mnt/sd_0/MeowAPPs/os.meow.hello/hello 2>/dev/null
cp -f /data/hello_app.json /usr/data/mnt/sd_0/MeowAPPs/os.meow.hello/app.json 2>/dev/null
chmod 755 /usr/data/mnt/sd_0/MeowAPPs/os.meow.hello/hello 2>/dev/null
rm -rf /data/overlay/theme1 /data/overlay/str_zh /data/overlay/str_en
cp -a /usr/resource/layout/theme1 /data/overlay/theme1
cp -a /usr/resource/str/simplified_chinese /data/overlay/str_zh
cp -a /usr/resource/str/english /data/overlay/str_en
cp -f /data/hiby_player_patched_v2 /data/overlay/hiby_player
chmod 755 /data/overlay/hiby_player
ls /usr/data/mnt/sd_0/MeowAPPs/os.meow.hello/ 2>/dev/null'
# 推 hello + 资源
timeout 30 $SSH root@$DEV "cat > /data/hello.bin" < "$HELLO"
timeout 30 $SSH root@$DEV "cat > /data/hello_app.json" < "$HJ"
cat > /tmp/vc.sftp << EOF
put $ASSETS/layout/theme1/hiby_apps_main.view /data/overlay/theme1/hiby_apps_main.view
put $ASSETS/str/simplified_chinese/apps.ini /data/overlay/str_zh/apps.ini
put $ASSETS/str/english/apps.ini /data/overlay/str_en/apps.ini
EOF
timeout 30 sftp -i "$KEY" -o StrictHostKeyChecking=accept-new -b /tmp/vc.sftp root@$DEV
s 'cp -f /data/hello.bin /usr/data/mnt/sd_0/MeowAPPs/os.meow.hello/hello
cp -f /data/hello_app.json /usr/data/mnt/sd_0/MeowAPPs/os.meow.hello/app.json
chmod 755 /usr/data/mnt/sd_0/MeowAPPs/os.meow.hello/hello
ls -la /usr/data/mnt/sd_0/MeowAPPs/os.meow.hello/'
}
restart() {
echo "== 重启播放器(安全顺序) =="
s 'rm -f /data/recovery_all'
echo "before: $(count_inst)"
s 'for pid in $(ps | grep "hiby_player.sh" | grep -v grep | awk "{print \$1}"); do kill $pid 2>/dev/null; done; sleep 1
for pid in $(ps | grep hiby_player | grep -v grep | grep -v "hiby_player.sh" | awk "{print \$1}"); do kill $pid 2>/dev/null; done; sleep 2
umount /usr/bin/hiby_player 2>/dev/null || true
umount /usr/resource/layout/theme1 2>/dev/null || true
umount /usr/resource/str/simplified_chinese 2>/dev/null || true
umount /usr/resource/str/english 2>/dev/null || true
echo "after_kill: $(ps | grep hiby_player | grep -v grep | wc -l)"
mount --bind /data/overlay/hiby_player /usr/bin/hiby_player
mount --bind /data/overlay/theme1 /usr/resource/layout/theme1
mount --bind /data/overlay/str_zh /usr/resource/str/simplified_chinese
mount --bind /data/overlay/str_en /usr/resource/str/english
echo "md5: $(md5sum /usr/bin/hiby_player | cut -c1-8)"
ls /usr/resource/layout/theme1/hiby_apps_main.view >/dev/null && echo view_ok
nohup /usr/bin/hiby_player >/tmp/hiby_player.log 2>&1 &
sleep 4
echo "instances: $(ps | grep hiby_player | grep -v grep | grep -v sh | wc -l)"'
}
stable() {
echo "== 稳定性: 60s 观察 =="
s 'n1=$(ps | grep hiby_player | grep -v grep | grep -v sh | wc -l); sleep 60;
n2=$(ps | grep hiby_player | grep -v grep | grep -v sh | wc -l)
ls /data/recovery_all 2>/dev/null && echo FLAG || echo no_flag
echo "instances: $n1 -> $n2"'
}
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" > "$SHOTDIR/$name.raw"
python3 "$SHOTDIR/fb2png.py" "$SHOTDIR/$name.raw" >/dev/null 2>&1
echo "saved device_test/$name.raw -> .png ($(stat -c%s "$SHOTDIR/$name.raw" 2>/dev/null) B)"
}
tap() {
# tap <x> <y> [dev]
local x=${1:-240} y=${2:-360} dev=${3:-/dev/input/event1}
s "/data/uinput_tap inject $x $y $dev >/dev/null 2>&1; echo done"
}
wake() {
echo "== 唤醒 =="
s 'echo 101 > /sys/class/backlight/backlight_pwm0/brightness
/data/keytap /dev/input/event0 116 2>/dev/null
sleep 2; echo "bkl=$(cat /sys/class/backlight/backlight_pwm0/brightness)"'
}
launcher() { tap 360 156; }
stream() { tap 355 207; }
back() { tap 240 630; }
case "${1:-}" in
check) check ;;
deploy) deploy ;;
restart) restart ;;
stable) stable ;;
wake) wake ;;
shot) shot "${2:-shot}" ;;
tap) tap "${2:-240}" "${3:-360}" ;;
launcher) launcher ;;
stream) stream ;;
back) back ;;
*) echo "usage: $0 check|deploy|restart|stable|wake|shot [name]|tap x y|launcher|stream|back"; exit 1 ;;
esac