test_termux_api.py 5.22 KB
#!/usr/bin/env python3
"""
Termux API 测试 — 验证通知读取、剪贴板、电量等 API 可用性。
在 Ubuntu proot 或 Termux 环境内执行。

注意:Termux API 需要安装 Termux:API 应用(com.termux.api)。
"""
import subprocess, json, sys, os

REPORT = {"test": "termux_api", "steps": {}, "overall": None}

def log_step(name, ok, detail=""):
    status = "[OK]" if ok else "[FAIL]"
    print(f"  {status} {name}")
    if detail:
        print(f"       {detail}")
    REPORT["steps"][name] = {"ok": ok, "detail": detail}
    return ok

def run_termux_api(cmd_args, timeout=10):
    """Run a termux-api command via termux-api daemon."""
    # termux-api commands are typically prefixed with `termux-`
    # They communicate with the Termux:API app via am broadcast internally
    termux_prefix = "/data/data/com.termux/files/usr/bin/"
    full_cmd = [termux_prefix + cmd_args[0]] + cmd_args[1:]
    try:
        r = subprocess.run(full_cmd, capture_output=True, text=True, timeout=timeout)
        return r.returncode == 0, r.stdout, r.stderr
    except Exception as e:
        return False, "", str(e)

def start_termux_api_service():
    """Start Termux:API background service if needed."""
    try:
        subprocess.run(
            ["/system/bin/am", "startservice", "-n", "com.termux.api/.TermuxApiService"],
            capture_output=True, timeout=5
        )
        time.sleep(2)  # Wait for service to start
    except Exception:
        pass

def main():
    print("=" * 60)
    print("Termux API 测试")
    print("=" * 60)

    all_ok = True

    # Step 0: Start Termux API service
    print("\n[Step 0] 启动 Termux:API 服务")
    start_termux_api_service()
    print("  [OK] TermuxApiService started")

    # Step 1: Check termux-api binary exists
    print("\n[Step 1] termux-api 命令可用性")
    termux_bin = "/data/data/com.termux/files/usr/bin/termux-notification-list"
    has_termux_api = os.path.exists(termux_bin)
    all_ok &= log_step("termux_api_binary", has_termux_api,
                       f"found={has_termux_api} path={termux_bin}" if has_termux_api else "未找到 termux-api 命令")

    if not has_termux_api:
        print("\n  [提示] 在 Termux 中安装:")
        print("       pkg install termux-api")
        print("       并安装 Termux:API 应用 (F-Droid 或 GitHub)")
        save_report()
        return 1

    # Step 2: Battery status
    print("\n[Step 2] 电量状态")
    ok, stdout, stderr = run_termux_api(["termux-battery-status"])
    if ok:
        try:
            battery = json.loads(stdout)
            detail = f"{battery.get('percentage', '?')}% {battery.get('status', '?')}"
        except:
            detail = stdout[:100]
    else:
        detail = stderr[:100]
    all_ok &= log_step("battery_status", ok, detail)

    # Step 3: Notification list (check if we can read notifications)
    print("\n[Step 3] 通知列表读取")
    ok, stdout, stderr = run_termux_api(["termux-notification-list"])
    wechat_notifs = []
    if ok:
        try:
            notifs = json.loads(stdout)
            wechat_notifs = [n for n in notifs if n.get("pkgName") == "com.tencent.mm"]
            detail = f"总通知={len(notifs)} 微信通知={len(wechat_notifs)}"
            if wechat_notifs:
                for n in wechat_notifs[:3]:
                    print(f"       [微信通知] {n.get('title', '?')}: {n.get('content', '?')[:60]}")
        except Exception as e:
            detail = f"parse error: {e} raw={stdout[:100]}"
    else:
        detail = stderr[:100]
    # Notification list is optional - may be empty if no WeChat notifications currently
    all_ok &= log_step("notification_list", ok, detail)
    if ok and not wechat_notifs:
        print("       [INFO] 当前通知列表中无微信通知(请让朋友发一条消息后再测试)")

    # Step 4: Clipboard (optional)
    print("\n[Step 4] 剪贴板读写 (可选)")
    test_clip = f"hermes_test_{os.urandom(4).hex()}"
    ok1, _, err1 = run_termux_api(["termux-clipboard-set", test_clip])
    ok2, stdout2, err2 = run_termux_api(["termux-clipboard-get"])
    clip_ok = ok1 and ok2 and test_clip in stdout2
    if clip_ok:
        log_step("clipboard", True, f"write={ok1} read={ok2} match={clip_ok}")
    else:
        log_step("clipboard", False, f"err={err1 or err2} (optional)")
        print("       [WARN] 剪贴板非核心功能,跳过")

    # Step 5: Send a test notification
    print("\n[Step 5] 发送测试通知")
    ok, stdout, stderr = run_termux_api([
        "termux-notification",
        "--title", "Hermes WeChat Test",
        "--content", "Termux API 测试通过",
        "--priority", "low"
    ])
    all_ok &= log_step("send_notification", ok, "sent test notification" if ok else stderr[:100])

    # Summary
    REPORT["overall"] = "PASS" if all_ok else "FAIL"
    REPORT["timestamp"] = subprocess.check_output(["date", "-Iseconds"]).decode().strip()

    save_report()

    print("\n" + "=" * 60)
    print(f"结果: {REPORT['overall']}")
    print("=" * 60)
    print("\n详细报告: test_report_termux_api.json")
    return 0 if all_ok else 1

def save_report():
    with open("test_report_termux_api.json", "w") as f:
        json.dump(REPORT, f, indent=2, ensure_ascii=False)

if __name__ == "__main__":
    sys.exit(main())