#!/bin/bash # verify_chain.sh — MeowAPPs 全链路真机验证编排(第五轮) # 用法: ./verify_chain.sh # 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="" KEY="$HOME/Project/R3ProII/ssh_keys/" 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 [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