Files
workphone-sdk/sdk/app/routers/adb.py

208 lines
5.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
工作手机SDK v3.0 - ADB设备路由
直接ADB控制模式支持模拟器和真机
所有端点使用 def非 async defFastAPI 自动在线程池中执行,
避免同步 ADB shell 命令阻塞事件循环。
"""
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import Optional
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from services.adb_device import adb_manager
router = APIRouter(prefix="/api/v3/adb", tags=["ADB设备控制"])
# ========== 请求模型 ==========
class ClickRequest(BaseModel):
x: int
y: int
class ClickTextRequest(BaseModel):
text: str
timeout: float = 10
class InputRequest(BaseModel):
text: str
clear: bool = True
class SwipeRequest(BaseModel):
direction: str
scale: float = 0.5
class AppRequest(BaseModel):
package: str
class KeyRequest(BaseModel):
key: str
# ========== 设备管理 ==========
@router.get("/devices")
def list_devices():
"""获取所有ADB设备"""
devices = adb_manager.list_devices()
return {"code": 200, "data": devices}
@router.get("/scan")
@router.post("/scan")
def scan_devices():
"""扫描设备(含未授权设备的完整信息)"""
serials = adb_manager.scan_devices()
all_devices = adb_manager.scan_all_devices()
return {
"code": 200,
"data": {
"devices": serials,
"all_devices": all_devices,
"authorized_count": len(serials),
"total_count": len(all_devices),
},
}
@router.get("/devices/{serial}")
def get_device_info(serial: str):
"""获取设备详情"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
info = device.get_info()
info["status"] = "online" if device.is_online() else "offline"
return {"code": 200, "data": info}
# ========== 基础操作 ==========
@router.post("/devices/{serial}/screenshot")
def screenshot(serial: str):
"""截图"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.screenshot()
@router.post("/devices/{serial}/click")
def click(serial: str, req: ClickRequest):
"""点击坐标"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.click(req.x, req.y)
@router.post("/devices/{serial}/click-text")
def click_text(serial: str, req: ClickTextRequest):
"""点击文字"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.click_text(req.text, req.timeout)
@router.post("/devices/{serial}/input")
def input_text(serial: str, req: InputRequest):
"""输入文字"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.input_text(req.text, req.clear)
@router.post("/devices/{serial}/swipe")
def swipe(serial: str, req: SwipeRequest):
"""滑动"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.swipe(req.direction, req.scale)
@router.post("/devices/{serial}/key")
def press_key(serial: str, req: KeyRequest):
"""按键"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.press_key(req.key)
# ========== APP操作 ==========
@router.post("/devices/{serial}/app/start")
def start_app(serial: str, req: AppRequest):
"""启动APP"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.start_app(req.package)
@router.post("/devices/{serial}/app/stop")
def stop_app(serial: str, req: AppRequest):
"""停止APP"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.stop_app(req.package)
@router.get("/devices/{serial}/app/current")
def current_app(serial: str):
"""获取当前APP"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.current_app()
@router.get("/devices/{serial}/app/list")
def list_apps(serial: str):
"""获取已安装APP"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
return device.installed_apps()
# ========== UI ==========
@router.get("/devices/{serial}/ui-tree")
def get_ui_tree(serial: str):
"""获取UI树XML 已做 JSON-safe 转义)"""
device = adb_manager.get_device(serial)
if not device:
raise HTTPException(status_code=404, detail="设备不存在")
result = device.get_ui_tree()
if isinstance(result, dict) and "data" in result:
xml = result["data"].get("xml", "")
if isinstance(xml, str):
result["data"]["xml"] = xml.replace("\x00", "").replace("\r", "")
return result