adb异常处理优化
This commit is contained in:
parent
b8b6285ff1
commit
db94be4e4c
3 changed files with 53 additions and 60 deletions
|
@ -4,7 +4,3 @@ class SimulatorError(Exception):
|
||||||
|
|
||||||
class GameError(Exception):
|
class GameError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ADBError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
|
@ -10,12 +10,18 @@ from adbutils import AdbClient, AdbDevice
|
||||||
from mower import __system__
|
from mower import __system__
|
||||||
from mower.utils import config
|
from mower.utils import config
|
||||||
from mower.utils.csleep import MowerExit, csleep
|
from mower.utils.csleep import MowerExit, csleep
|
||||||
|
from mower.utils.device.exception import SimulatorError
|
||||||
|
from mower.utils.device.simulator import restart_simulator
|
||||||
from mower.utils.image import bytes2img
|
from mower.utils.image import bytes2img
|
||||||
from mower.utils.log import logger
|
from mower.utils.log import logger
|
||||||
|
|
||||||
from .utils import subprocess_run
|
from .utils import subprocess_run
|
||||||
|
|
||||||
|
|
||||||
|
class ADBServerError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def retry_adb(func):
|
def retry_adb(func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def retry_wrapper(self, *args, **kwargs):
|
def retry_wrapper(self, *args, **kwargs):
|
||||||
|
@ -24,9 +30,15 @@ def retry_adb(func):
|
||||||
return func(self, *args, **kwargs)
|
return func(self, *args, **kwargs)
|
||||||
except MowerExit:
|
except MowerExit:
|
||||||
raise
|
raise
|
||||||
|
except ADBServerError as e:
|
||||||
|
logger.exception(e)
|
||||||
|
self.restart_server()
|
||||||
|
except SimulatorError as e:
|
||||||
|
logger.exception(e)
|
||||||
|
restart_simulator()
|
||||||
|
self._adb_device = None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
self.adb_reconnect()
|
|
||||||
|
|
||||||
return retry_wrapper
|
return retry_wrapper
|
||||||
|
|
||||||
|
@ -38,7 +50,6 @@ class ADB:
|
||||||
self._adb_device = None # 用于存储 AdbDevice 实例
|
self._adb_device = None # 用于存储 AdbDevice 实例
|
||||||
self.check_server_status()
|
self.check_server_status()
|
||||||
|
|
||||||
@retry_adb
|
|
||||||
def get_adb_client(self) -> AdbClient:
|
def get_adb_client(self) -> AdbClient:
|
||||||
"""
|
"""
|
||||||
Returns an AdbClient instance.
|
Returns an AdbClient instance.
|
||||||
|
@ -47,9 +58,9 @@ class ADB:
|
||||||
if self._adb_client is None:
|
if self._adb_client is None:
|
||||||
try:
|
try:
|
||||||
self.check_server_status()
|
self.check_server_status()
|
||||||
self._adb_client = AdbClient("127.0.0.1", config.adb_server_port, 5)
|
self._adb_client = AdbClient("127.0.0.1", config.adb_server_port, 10)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise ADBServerError(e)
|
||||||
return self._adb_client
|
return self._adb_client
|
||||||
|
|
||||||
@retry_adb
|
@retry_adb
|
||||||
|
@ -60,9 +71,20 @@ class ADB:
|
||||||
"""
|
"""
|
||||||
if self._adb_device is None:
|
if self._adb_device is None:
|
||||||
adb_client = self.get_adb_client()
|
adb_client = self.get_adb_client()
|
||||||
if len(adb_client.list()) == 0:
|
if len(devices := adb_client.list()) == 0:
|
||||||
adb_client.connect(config.conf.adb, 5)
|
try:
|
||||||
|
adb_client.connect(config.conf.adb, 10)
|
||||||
|
except Exception as e:
|
||||||
|
raise SimulatorError(e)
|
||||||
|
elif devices[0].state == "offline":
|
||||||
|
try:
|
||||||
|
adb_client.disconnect(config.conf.adb)
|
||||||
|
adb_client.connect(config.conf.adb, 10)
|
||||||
|
except Exception as e:
|
||||||
|
raise SimulatorError(e)
|
||||||
|
|
||||||
self._adb_device = AdbDevice(adb_client, config.conf.adb)
|
self._adb_device = AdbDevice(adb_client, config.conf.adb)
|
||||||
|
self.check_device_status()
|
||||||
return self._adb_device
|
return self._adb_device
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -92,9 +114,13 @@ class ADB:
|
||||||
Returns:
|
Returns:
|
||||||
str:
|
str:
|
||||||
"""
|
"""
|
||||||
cmd = list(map(str, cmd))
|
try:
|
||||||
cmd = [self.adb_bin, "-P", str(config.adb_server_port)] + cmd
|
cmd = list(map(str, cmd))
|
||||||
return subprocess_run(cmd, timeout=timeout)
|
cmd = [self.adb_bin, "-P", str(config.adb_server_port)] + cmd
|
||||||
|
return subprocess_run(cmd, timeout=timeout)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(e)
|
||||||
|
self.check_device_status()
|
||||||
|
|
||||||
def check_server_status(self) -> str:
|
def check_server_status(self) -> str:
|
||||||
"""Use `adb devices` as `adb start-server`, result is actually useless"""
|
"""Use `adb devices` as `adb start-server`, result is actually useless"""
|
||||||
|
@ -106,21 +132,11 @@ class ADB:
|
||||||
self.adb_command(["kill-server"])
|
self.adb_command(["kill-server"])
|
||||||
self._adb_client = self._adb_device = None
|
self._adb_client = self._adb_device = None
|
||||||
|
|
||||||
def restart_server(self) -> None:
|
|
||||||
self.kill_server()
|
|
||||||
self.check_server_status()
|
|
||||||
|
|
||||||
def adb_disconnect(self):
|
def adb_disconnect(self):
|
||||||
self.adb_client.disconnect(config.conf.adb, raise_error=False)
|
self.adb_client.disconnect(config.conf.adb, raise_error=False)
|
||||||
self._adb_device = None
|
self._adb_device = None
|
||||||
|
|
||||||
def adb_reconnect(self):
|
@retry_adb
|
||||||
status = self.check_server_status()
|
|
||||||
if "offline" in status:
|
|
||||||
self.adb_disconnect()
|
|
||||||
else:
|
|
||||||
self.restart_server()
|
|
||||||
|
|
||||||
def adb_shell(
|
def adb_shell(
|
||||||
self, cmd, stream=False, timeout=20, encoding: str | None = "utf-8", rstrip=True
|
self, cmd, stream=False, timeout=20, encoding: str | None = "utf-8", rstrip=True
|
||||||
):
|
):
|
||||||
|
@ -136,17 +152,28 @@ class ADB:
|
||||||
str if stream=False
|
str if stream=False
|
||||||
socket if stream=True
|
socket if stream=True
|
||||||
"""
|
"""
|
||||||
if not isinstance(cmd, str):
|
try:
|
||||||
cmd = list(map(str, cmd))
|
if not isinstance(cmd, str):
|
||||||
|
cmd = list(map(str, cmd))
|
||||||
|
|
||||||
return self.adb.shell(
|
return self.adb.shell(
|
||||||
cmd, stream=stream, timeout=timeout, encoding=encoding, rstrip=rstrip
|
cmd, stream=stream, timeout=timeout, encoding=encoding, rstrip=rstrip
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(cmd)
|
||||||
|
logger.exception(e)
|
||||||
|
self.check_device_status()
|
||||||
|
|
||||||
def adb_push(self, file_path: str, target: str):
|
def adb_push(self, file_path: str, target: str):
|
||||||
"""push file into device with adb_bin"""
|
"""push file into device with adb_bin"""
|
||||||
self.adb.push(file_path, target)
|
self.adb.push(file_path, target)
|
||||||
|
|
||||||
|
def check_device_status(self):
|
||||||
|
try:
|
||||||
|
self.adb.shell("echo test")
|
||||||
|
except Exception:
|
||||||
|
raise SimulatorError("设备未连接")
|
||||||
|
|
||||||
def process(
|
def process(
|
||||||
self, path: str, args: list[str] = [], stderr: int = subprocess.DEVNULL
|
self, path: str, args: list[str] = [], stderr: int = subprocess.DEVNULL
|
||||||
) -> subprocess.Popen:
|
) -> subprocess.Popen:
|
||||||
|
@ -259,6 +286,7 @@ class ADB:
|
||||||
|
|
||||||
|
|
||||||
class DIY:
|
class DIY:
|
||||||
|
@retry_adb
|
||||||
def capture_display():
|
def capture_display():
|
||||||
command = config.conf.custom_screenshot.command
|
command = config.conf.custom_screenshot.command
|
||||||
data = subprocess.check_output(
|
data = subprocess.check_output(
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import functools
|
|
||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
@ -13,7 +12,6 @@ from adbutils import AdbConnection, Network
|
||||||
from mower.utils import config
|
from mower.utils import config
|
||||||
from mower.utils import typealias as tp
|
from mower.utils import typealias as tp
|
||||||
from mower.utils.csleep import MowerExit
|
from mower.utils.csleep import MowerExit
|
||||||
from mower.utils.device.exception import ADBError
|
|
||||||
from mower.utils.device.method.adb import ADB
|
from mower.utils.device.method.adb import ADB
|
||||||
from mower.utils.device.method.adb.const import KeyCode
|
from mower.utils.device.method.adb.const import KeyCode
|
||||||
from mower.utils.log import logger
|
from mower.utils.log import logger
|
||||||
|
@ -192,35 +190,6 @@ class Client:
|
||||||
self.control_socket.close()
|
self.control_socket.close()
|
||||||
self.control_socket = None
|
self.control_socket = None
|
||||||
|
|
||||||
def stable(f):
|
|
||||||
@functools.wraps(f)
|
|
||||||
def inner(self: Client, *args, **kwargs):
|
|
||||||
try_count = 0
|
|
||||||
while try_count < 3:
|
|
||||||
try:
|
|
||||||
return f(self, *args, **kwargs)
|
|
||||||
except (
|
|
||||||
ConnectionResetError,
|
|
||||||
BrokenPipeError,
|
|
||||||
ConnectionAbortedError,
|
|
||||||
) as e:
|
|
||||||
logger.debug_exception(e)
|
|
||||||
self.stop()
|
|
||||||
time.sleep(1)
|
|
||||||
self.start()
|
|
||||||
try_count += 1
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception(e)
|
|
||||||
self.stop()
|
|
||||||
time.sleep(1)
|
|
||||||
self.start()
|
|
||||||
try_count += 1
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise ADBError("Failed to start scrcpy-server.")
|
|
||||||
|
|
||||||
return inner
|
|
||||||
|
|
||||||
@retry_scrcpy
|
@retry_scrcpy
|
||||||
def tap(self, x: int, y: int) -> None:
|
def tap(self, x: int, y: int) -> None:
|
||||||
self.control.tap(x, y)
|
self.control.tap(x, y)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue