Skip to content

Commit fe55825

Browse files
authored
Merge pull request #574 from mahbd/upload-android-ui
Android inspector for ZeuZ
2 parents c3c27c8 + d736418 commit fe55825

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

server/main.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
import threading
23
from typing import Any
34
from fastapi import APIRouter, FastAPI
45
from fastapi.middleware.cors import CORSMiddleware
@@ -7,7 +8,7 @@
78
from server.connect import router as connect_router
89
from server.evaluator import router as evaluator_router
910
from server.node_operator import router as operator_router
10-
from server.mobile import router as mobile_router
11+
from server.mobile import router as mobile_router, upload_android_ui_dump
1112
from server.mac import router as mac_router
1213

1314
class EndpointFilter(logging.Filter):
@@ -26,6 +27,8 @@ def filter(self, record: logging.LogRecord) -> bool:
2627
def main() -> FastAPI:
2728
# Filter out /endpoint
2829
logging.getLogger("uvicorn.access").addFilter(EndpointFilter(path="/status"))
30+
thread = threading.Thread(target=upload_android_ui_dump, daemon=True)
31+
thread.start()
2932

3033
v1router = APIRouter(
3134
prefix="/api/v1",

server/mobile.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
1+
import hashlib
12
import os
23
import subprocess
34
import base64
5+
import time
46
from typing import Literal
7+
8+
import requests
59
from fastapi import APIRouter
610
from pydantic import BaseModel
711

12+
from Framework.Utilities import ConfigModule, CommonUtil
13+
814
ADB_PATH = "adb" # Ensure ADB is in PATH
915
UI_XML_PATH = "ui.xml"
1016
SCREENSHOT_PATH = "screen.png"
1117

1218
router = APIRouter(prefix="/mobile", tags=["mobile"])
1319

20+
1421
class InspectorResponse(BaseModel):
1522
"""Response model for the /inspector endpoint."""
1623

@@ -19,6 +26,7 @@ class InspectorResponse(BaseModel):
1926
screenshot: str | None = None # Base64 encoded image
2027
error: str | None = None
2128

29+
2230
class DeviceInfo(BaseModel):
2331
"""Model for device information."""
2432
serial: str
@@ -128,3 +136,38 @@ def capture_screenshot():
128136
out = run_adb_command(f"{ADB_PATH} pull /sdcard/screen.png {SCREENSHOT_PATH}")
129137
if out.startswith("Error:"):
130138
return
139+
140+
141+
def upload_android_ui_dump():
142+
prev_xml_hash = ""
143+
while True:
144+
try:
145+
capture_ui_dump()
146+
try:
147+
with open(UI_XML_PATH, 'r') as xml_file:
148+
xml_content = xml_file.read()
149+
xml_content = xml_content.replace("<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>", "", 1)
150+
new_xml_hash = hashlib.sha256(xml_content.encode('utf-8')).hexdigest()
151+
# Don't upload if the content hasn't changed
152+
if prev_xml_hash == new_xml_hash:
153+
time.sleep(5)
154+
continue
155+
prev_xml_hash = new_xml_hash
156+
157+
except FileNotFoundError:
158+
time.sleep(5)
159+
continue
160+
url = ConfigModule.get_config_value("Authentication", "server_address").strip() + "/node_ai_contents/"
161+
apiKey = ConfigModule.get_config_value("Authentication", "api-key").strip()
162+
res = requests.post(
163+
url,
164+
headers={"X-Api-Key": apiKey},
165+
json={
166+
"dom_mob": {"dom": xml_content},
167+
"node_id": CommonUtil.MachineInfo().getLocalUser().lower()
168+
})
169+
if res.ok:
170+
CommonUtil.ExecLog("", "UI dump uploaded successfully", iLogLevel=1)
171+
except Exception as e:
172+
CommonUtil.ExecLog("", f"Error uploading UI dump: {str(e)}", iLogLevel=3)
173+
time.sleep(5)

0 commit comments

Comments
 (0)