uiautodev 0.7.2__tar.gz → 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of uiautodev might be problematic. Click here for more details.

Files changed (38) hide show
  1. {uiautodev-0.7.2 → uiautodev-0.8.0}/PKG-INFO +1 -1
  2. {uiautodev-0.7.2 → uiautodev-0.8.0}/pyproject.toml +1 -1
  3. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/__init__.py +1 -1
  4. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/app.py +19 -2
  5. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/driver/android.py +9 -0
  6. uiautodev-0.8.0/uiautodev/router/android.py +42 -0
  7. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/router/device.py +2 -17
  8. {uiautodev-0.7.2 → uiautodev-0.8.0}/LICENSE +0 -0
  9. {uiautodev-0.7.2 → uiautodev-0.8.0}/README.md +0 -0
  10. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/__main__.py +0 -0
  11. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/appium_proxy.py +0 -0
  12. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/binaries/scrcpy_server.jar +0 -0
  13. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/case.py +0 -0
  14. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/cli.py +0 -0
  15. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/command_proxy.py +0 -0
  16. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/command_types.py +0 -0
  17. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/common.py +0 -0
  18. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/driver/appium.py +0 -0
  19. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/driver/base_driver.py +0 -0
  20. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/driver/harmony.py +0 -0
  21. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/driver/ios.py +0 -0
  22. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/driver/mock.py +0 -0
  23. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/driver/testdata/layout.json +0 -0
  24. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/driver/udt/appium-uiautomator2-v5.12.4-light.apk +0 -0
  25. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/driver/udt/udt.py +0 -0
  26. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/exceptions.py +0 -0
  27. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/model.py +0 -0
  28. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/provider.py +0 -0
  29. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/remote/android_input.py +0 -0
  30. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/remote/keycode.py +0 -0
  31. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/remote/scrcpy.py +0 -0
  32. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/remote/touch_controller.py +0 -0
  33. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/router/xml.py +0 -0
  34. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/static/demo.html +0 -0
  35. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/utils/common.py +0 -0
  36. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/utils/envutils.py +0 -0
  37. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/utils/exceptions.py +0 -0
  38. {uiautodev-0.7.2 → uiautodev-0.8.0}/uiautodev/utils/usbmux.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: uiautodev
3
- Version: 0.7.2
3
+ Version: 0.8.0
4
4
  Summary: Mobile UI Automation, include UI hierarchy inspector, script recorder
5
5
  License: MIT
6
6
  Author: codeskyblue
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "uiautodev"
3
- version = "0.7.2"
3
+ version = "0.8.0"
4
4
  description = "Mobile UI Automation, include UI hierarchy inspector, script recorder"
5
5
  homepage = "https://uiauto.dev"
6
6
  authors = ["codeskyblue <codeskyblue@gmail.com>"]
@@ -5,4 +5,4 @@
5
5
  """
6
6
 
7
7
  # version is auto managed by poetry
8
- __version__ = "0.7.2"
8
+ __version__ = "0.8.0"
@@ -9,7 +9,7 @@ import os
9
9
  import platform
10
10
  import signal
11
11
  from pathlib import Path
12
- from typing import List
12
+ from typing import Dict, List
13
13
 
14
14
  import adbutils
15
15
  import uvicorn
@@ -25,6 +25,7 @@ from uiautodev.common import convert_bytes_to_image, get_webpage_url, ocr_image
25
25
  from uiautodev.model import Node
26
26
  from uiautodev.provider import AndroidProvider, HarmonyProvider, IOSProvider, MockProvider
27
27
  from uiautodev.remote.scrcpy import ScrcpyServer
28
+ from uiautodev.router.android import router as android_device_router
28
29
  from uiautodev.router.device import make_router
29
30
  from uiautodev.router.xml import router as xml_router
30
31
  from uiautodev.utils.envutils import Environment
@@ -68,7 +69,23 @@ else:
68
69
  app.include_router(harmony_router, prefix="/api/harmony", tags=["harmony"])
69
70
 
70
71
  app.include_router(xml_router, prefix="/api/xml", tags=["xml"])
71
-
72
+ app.include_router(android_device_router, prefix="/api/android", tags=["android"])
73
+
74
+
75
+ @app.get('/api/{platform}/features')
76
+ def get_features(platform: str) -> Dict[str, bool]:
77
+ """Get features supported by the specified platform"""
78
+ features = {}
79
+ # 获取所有带有指定平台tag的路由
80
+ for route in app.routes:
81
+ if hasattr(route, 'tags') and platform in route.tags:
82
+ if route.path.startswith(f"/api/{platform}/{{serial}}/"):
83
+ # 提取特性名称
84
+ parts = route.path.split('/')
85
+ feature_name = parts[-1]
86
+ if not feature_name.startswith('{'):
87
+ features[feature_name] = True
88
+ return features
72
89
 
73
90
  class InfoResponse(BaseModel):
74
91
  version: str
@@ -31,6 +31,15 @@ class AndroidDriver(BaseDriver):
31
31
  @cached_property
32
32
  def ud(self) -> u2.Device:
33
33
  return u2.connect_usb(self.serial)
34
+
35
+ def get_current_activity(self) -> str:
36
+ ret = self.adb_device.shell2(["dumpsys", "activity", "activities"], rstrip=True, timeout=5)
37
+ # 使用正则查找包含前台 activity 的行
38
+ match = re.search(r"mResumedActivity:.*? ([\w\.]+\/[\w\.]+)", ret.output)
39
+ if match:
40
+ return match.group(1) # 返回包名/类名,例如 com.example/.MainActivity
41
+ else:
42
+ return ""
34
43
 
35
44
  def screenshot(self, id: int) -> Image.Image:
36
45
  if id > 0:
@@ -0,0 +1,42 @@
1
+ # prefix for /api/android/{serial}/shell
2
+
3
+ import logging
4
+ from typing import Dict, Optional
5
+
6
+ from fastapi import APIRouter, Request, Response
7
+ from pydantic import BaseModel
8
+
9
+ from uiautodev.driver.android import AndroidDriver
10
+ from uiautodev.model import ShellResponse
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ router = APIRouter()
15
+
16
+
17
+ class AndroidShellPayload(BaseModel):
18
+ command: str
19
+
20
+ @router.post("/{serial}/shell")
21
+ def shell(serial: str, payload: AndroidShellPayload) -> ShellResponse:
22
+ """Run a shell command on an Android device"""
23
+ try:
24
+ driver = AndroidDriver(serial)
25
+ return driver.shell(payload.command)
26
+ except NotImplementedError as e:
27
+ return Response(content="shell not implemented", media_type="text/plain", status_code=501)
28
+ except Exception as e:
29
+ logger.exception("shell failed")
30
+ return ShellResponse(output="", error=str(e))
31
+
32
+
33
+ @router.get("/{serial}/current_activity")
34
+ async def get_current_activity(serial: str) -> Response:
35
+ """Get the current activity of the Android device"""
36
+ try:
37
+ driver = AndroidDriver(serial)
38
+ activity = driver.get_current_activity()
39
+ return Response(content=activity, media_type="text/plain")
40
+ except Exception as e:
41
+ logger.exception("get_current_activity failed")
42
+ return Response(content="", media_type="text/plain")
@@ -6,9 +6,9 @@
6
6
 
7
7
  import io
8
8
  import logging
9
- from typing import Any, Dict, List
9
+ from typing import Any, Dict, List, Optional
10
10
 
11
- from fastapi import APIRouter, Response
11
+ from fastapi import APIRouter, Query, Request, Response
12
12
  from fastapi.responses import StreamingResponse
13
13
  from pydantic import BaseModel
14
14
 
@@ -19,9 +19,6 @@ from uiautodev.provider import BaseProvider
19
19
 
20
20
  logger = logging.getLogger(__name__)
21
21
 
22
- class AndroidShellPayload(BaseModel):
23
- command: str
24
-
25
22
 
26
23
  def make_router(provider: BaseProvider) -> APIRouter:
27
24
  router = APIRouter()
@@ -37,18 +34,6 @@ def make_router(provider: BaseProvider) -> APIRouter:
37
34
  logger.exception("list_devices failed")
38
35
  return Response(content=str(e), media_type="text/plain", status_code=500)
39
36
 
40
- @router.post("/{serial}/shell")
41
- def android_shell(serial: str, payload: AndroidShellPayload) -> ShellResponse:
42
- """Run a shell command on an Android device"""
43
- try:
44
- driver = provider.get_device_driver(serial)
45
- return driver.shell(payload.command)
46
- except NotImplementedError as e:
47
- return Response(content="shell not implemented", media_type="text/plain", status_code=501)
48
- except Exception as e:
49
- logger.exception("shell failed")
50
- return ShellResponse(output="", error=str(e))
51
-
52
37
  @router.get(
53
38
  "/{serial}/screenshot/{id}",
54
39
  responses={200: {"content": {"image/jpeg": {}}}},
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes