Skip to content

Commit 4e63c9d

Browse files
Added an new endpoint to download installer related logs
1 parent f99a5c8 commit 4e63c9d

21 files changed

Lines changed: 624 additions & 491 deletions

Framework/install_handler/android/adb.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
import asyncio
33
import platform
44
import os
5+
from Framework.install_handler.install_log_config import get_logger
56
from Framework.install_handler.utils import send_response
67
from Framework.install_handler.android.android_sdk import update_android_sdk_path
78

9+
logger = get_logger()
10+
811

912
async def check_status() -> bool:
1013
"""Check if ADB (Android Debug Bridge) is installed."""
11-
print("[installer][android-adb] Checking status...")
14+
logger.info("[installer][android-adb] Checking status...")
1215

1316
try:
1417

@@ -26,7 +29,7 @@ async def check_status() -> bool:
2629
# If command succeeds (returncode = 0), ADB is installed
2730
if result.returncode == 0:
2831
version_output = (result.stdout or result.stderr).strip()
29-
print(f"[installer][android-adb] Already installed")
32+
logger.info("[installer][android-adb] Already installed")
3033
await send_response({
3134
"action": "status",
3235
"data": {
@@ -38,7 +41,7 @@ async def check_status() -> bool:
3841
})
3942
return True
4043
else:
41-
print("[installer][android-adb] Not installed")
44+
logger.info("[installer][android-adb] Not installed")
4245
await send_response({
4346
"action": "status",
4447
"data": {
@@ -50,7 +53,7 @@ async def check_status() -> bool:
5053
})
5154
return False
5255
except Exception as e:
53-
print(f"[installer][android-adb] Error checking status: {e}")
56+
logger.error("[installer][android-adb] Error checking status: %s", e)
5457
await send_response({
5558
"action": "status",
5659
"data": {
@@ -67,15 +70,15 @@ async def check_status() -> bool:
6770

6871
async def install():
6972
"""Install ADB - checks if already installed, otherwise prompts to install Android SDK."""
70-
print("[installer][android-adb] Installing...")
73+
logger.info("[installer][android-adb] Installing...")
7174

7275
# Check if ADB is already installed
7376
if await check_status():
74-
print("[installer][android-adb] ADB is already installed")
77+
logger.info("[installer][android-adb] ADB is already installed")
7578
return
7679

7780
# ADB is not installed, send response to install Android SDK
78-
print("[installer][android-adb] ADB is not installed. Install Android SDK to get ADB.")
81+
logger.info("[installer][android-adb] ADB is not installed. Install Android SDK to get ADB.")
7982
await send_response({
8083
"action": "status",
8184
"data": {

Framework/install_handler/android/android_sdk.py

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,26 @@
44
import shutil
55
import zipfile
66
import subprocess
7+
import traceback
78
from pathlib import Path
89
import httpx
10+
from Framework.install_handler.install_log_config import get_logger
911
from Framework.install_handler.utils import send_response
1012
from settings import ZEUZ_NODE_DOWNLOADS_DIR
1113

14+
logger = get_logger()
15+
1216

1317
async def check_status() -> bool:
1418
"""Check if Android SDK is installed in isolated directory (following Node.js installer pattern)."""
15-
print("[installer][android-sdk] Checking status...")
19+
logger.info("[installer][android-sdk] Checking status...")
1620

1721
# Simple file existence check in isolated directory (like Node.js installer)
1822
adb_path = get_adb_path()
1923

2024
if adb_path.exists():
2125
sdk_root = _get_sdk_root()
22-
print(f"[installer][android-sdk] Already installed at {sdk_root}")
26+
logger.info("[installer][android-sdk] Already installed at %s", sdk_root)
2327

2428

2529
await send_response({
@@ -34,7 +38,7 @@ async def check_status() -> bool:
3438
return True
3539

3640
# Not installed
37-
print("[installer][android-sdk] Not installed")
41+
logger.info("[installer][android-sdk] Not installed")
3842
await send_response({
3943
"action": "status",
4044
"data": {
@@ -73,13 +77,13 @@ def update_android_sdk_path():
7377
# Check if SDK exists
7478
adb_path = get_adb_path()
7579
if not adb_path.exists():
76-
print("[installer][android-sdk] Warning: Android SDK not found for PATH update.")
80+
logger.warning("[installer][android-sdk] Warning: Android SDK not found for PATH update.")
7781
return
7882

7983
# Set ANDROID_HOME and ANDROID_SDK_ROOT for current process
8084
os.environ['ANDROID_HOME'] = str(sdk_root)
8185
os.environ['ANDROID_SDK_ROOT'] = str(sdk_root)
82-
print(f"[installer][android-sdk] ANDROID_HOME set for current process: {sdk_root}")
86+
logger.info("[installer][android-sdk] ANDROID_HOME set for current process: %s", sdk_root)
8387

8488
# Add SDK paths to PATH for current process (prepend so they take precedence)
8589
sdk_paths = [
@@ -93,7 +97,7 @@ def update_android_sdk_path():
9397
# Always prepend to ensure isolated SDK takes precedence (even if path already exists)
9498
os.environ['PATH'] = f"{sdk_path}{os.pathsep}{current_path}"
9599
current_path = os.environ['PATH']
96-
print(f"[installer][android-sdk] Prepended to current process PATH: {sdk_path}")
100+
logger.info("[installer][android-sdk] Prepended to current process PATH: %s", sdk_path)
97101

98102

99103
def _get_cmdline_tools_url() -> str:
@@ -117,7 +121,7 @@ async def _download_cmdline_tools(archive_path: Path) -> bool:
117121
archive_path.parent.mkdir(parents=True, exist_ok=True)
118122

119123

120-
print(f"[installer][android-sdk] Downloading Android Command Line Tools to {archive_path}...")
124+
logger.info("[installer][android-sdk] Downloading Android Command Line Tools to %s...", archive_path)
121125
await send_response({
122126
"action": "status",
123127
"data": {
@@ -136,19 +140,19 @@ async def _download_cmdline_tools(archive_path: Path) -> bool:
136140
total_size = int(response.headers.get("content-length", 0))
137141
downloaded = 0
138142
chunk = 8192
139-
counts = []
143+
last_pct = [-1]
140144
with open(archive_path, "wb") as f:
141145
async for data in response.aiter_bytes(chunk):
142146
f.write(data)
143147
downloaded += len(data)
144148
if total_size > 0:
145149
progress = (downloaded / total_size) * 100
146-
mb_d = downloaded / (1024 * 1024)
147-
mb_t = total_size / (1024 * 1024)
148-
print(f"\r[installer][android-sdk] Download {progress:.1f}% ({mb_d:.1f}/{mb_t:.1f} MB)", end='', flush=True)
149-
p = round(mb_d/mb_t, 1)
150-
if p not in counts:
151-
counts.append(p)
150+
pct = int(progress)
151+
if pct != last_pct[0]:
152+
last_pct[0] = pct
153+
mb_d = downloaded / (1024 * 1024)
154+
mb_t = total_size / (1024 * 1024)
155+
logger.info("[installer][android-sdk] Download %d%% (%.1f/%.1f MB)", pct, mb_d, mb_t)
152156
await send_response({
153157
"action": "status",
154158
"data": {
@@ -158,11 +162,10 @@ async def _download_cmdline_tools(archive_path: Path) -> bool:
158162
"comment": f"Downloading Android Command Line Tools... {progress:.1f}% ({mb_d:.1f}/{mb_t:.1f} MB)",
159163
}
160164
})
161-
print()
162-
print(f"[installer][android-sdk] Download complete: {archive_path}")
165+
logger.info("[installer][android-sdk] Download complete: %s", archive_path)
163166
return True
164167
except Exception as e:
165-
print(f"\n[installer][android-sdk] Download failed: {e}")
168+
logger.error("[installer][android-sdk] Download failed: %s", e)
166169
await send_response({
167170
"action": "status",
168171
"data": {
@@ -206,7 +209,7 @@ async def _extract_cmdline_tools(archive_path: Path, sdk_root: Path) -> bool:
206209
# If already extracted, clean stale zip and exit success
207210
sdkmanager = _find_executable(latest_dir / "bin", "sdkmanager")
208211
if sdkmanager:
209-
print("[installer][android-sdk] Command Line Tools already extracted")
212+
logger.info("[installer][android-sdk] Command Line Tools already extracted")
210213
try:
211214
if archive_path.exists():
212215
archive_path.unlink()
@@ -215,7 +218,7 @@ async def _extract_cmdline_tools(archive_path: Path, sdk_root: Path) -> bool:
215218
return True
216219

217220

218-
print("[installer][android-sdk] Extracting Android Command Line Tools...")
221+
logger.info("[installer][android-sdk] Extracting Android Command Line Tools...")
219222
await send_response({
220223
"action": "status",
221224
"data": {
@@ -265,10 +268,10 @@ async def _extract_cmdline_tools(archive_path: Path, sdk_root: Path) -> bool:
265268
pass
266269

267270

268-
print("[installer][android-sdk] Extraction complete")
271+
logger.info("[installer][android-sdk] Extraction complete")
269272
return True
270273
except Exception as e:
271-
print(f"[installer][android-sdk] Extraction failed: {e}")
274+
logger.error("[installer][android-sdk] Extraction failed: %s", e)
272275
await send_response({
273276
"action": "status",
274277
"data": {
@@ -293,7 +296,7 @@ async def _run_sdkmanager(sdk_root: Path, args: list[str]) -> bool:
293296
try:
294297
sdkmanager = _find_sdkmanager(sdk_root)
295298
if not sdkmanager:
296-
print("[installer][android-sdk] sdkmanager not found")
299+
logger.info("[installer][android-sdk] sdkmanager not found")
297300
return False
298301

299302
import asyncio
@@ -309,8 +312,8 @@ async def _run_sdkmanager(sdk_root: Path, args: list[str]) -> bool:
309312
# Wrap each arg in single quotes to preserve semicolons in package names like "platforms;android-36"
310313
quoted_args = " ".join([f"'{arg}'" for arg in args])
311314
shell_cmd = f'powershell -Command "{yes_responses} | &\\"{str(sdkmanager)}\\" --sdk_root={sdk_root} {quoted_args}"'
312-
print(f"[installer][android-sdk] Running: sdkmanager {' '.join(args)}")
313-
print(f"[installer][android-sdk] This may take 5-15 minutes to download ~450MB of components...")
315+
logger.info("[installer][android-sdk] Running: sdkmanager %s", " ".join(args))
316+
logger.info("[installer][android-sdk] This may take 5-15 minutes to download ~450MB of components...")
314317

315318
loop = asyncio.get_event_loop()
316319

@@ -333,10 +336,10 @@ def run_sdkmanager():
333336
try:
334337
for line in iter(process.stdout.readline, ''):
335338
if line:
336-
print(line.rstrip()) # Print immediately
339+
logger.info("%s", line.rstrip())
337340
output_lines.append(line.strip())
338341
except Exception as e:
339-
print(f"[installer][android-sdk] Output reading error: {e}")
342+
logger.error("[installer][android-sdk] Output reading error: %s", e)
340343

341344
process.stdout.close()
342345
returncode = process.wait(timeout=1800)
@@ -353,7 +356,7 @@ class Result:
353356
elif system == "Linux":
354357
# Linux can execute directly
355358
cmd = [str(sdkmanager), f"--sdk_root={sdk_root}"] + args
356-
print(f"[installer][android-sdk] Running: {' '.join(cmd)}")
359+
logger.info("[installer][android-sdk] Running: %s", " ".join(cmd))
357360

358361
loop = asyncio.get_event_loop()
359362
result = await loop.run_in_executor(
@@ -369,7 +372,7 @@ class Result:
369372
elif system == "Darwin":
370373
# macOS can execute directly
371374
cmd = [str(sdkmanager), f"--sdk_root={sdk_root}"] + args
372-
print(f"[installer][android-sdk] Running: {' '.join(cmd)}")
375+
logger.info("[installer][android-sdk] Running: %s", " ".join(cmd))
373376

374377
loop = asyncio.get_event_loop()
375378
result = await loop.run_in_executor(
@@ -383,25 +386,24 @@ class Result:
383386
)
384387
output = (result.stdout or "") + (result.stderr or "")
385388
else:
386-
print(f"[installer][android-sdk] Unsupported platform: {system}")
389+
logger.warning("[installer][android-sdk] Unsupported platform: %s", system)
387390
return False
388391

389392
if result.returncode != 0:
390-
print(f"[installer][android-sdk] sdkmanager failed (returncode={result.returncode})")
393+
logger.error("[installer][android-sdk] sdkmanager failed (returncode=%s)", result.returncode)
391394
if output:
392-
print(f"[installer][android-sdk] Last output:\n{output}")
395+
logger.error("[installer][android-sdk] Last output:\n%s", output)
393396
return False
394397

395-
print(f"[installer][android-sdk] sdkmanager completed successfully")
398+
logger.info("[installer][android-sdk] sdkmanager completed successfully")
396399
if output:
397-
print(f"[installer][android-sdk] Final output:\n{output[-500:]}") # Last 500 chars
400+
logger.info("[installer][android-sdk] Final output:\n%s", output[-500:])
398401
return True
399402
except subprocess.TimeoutExpired:
400-
print("[installer][android-sdk] sdkmanager timed out after 30 minutes")
403+
logger.warning("[installer][android-sdk] sdkmanager timed out after 30 minutes")
401404
return False
402405
except Exception as e:
403-
print(f"[installer][android-sdk] sdkmanager error: {e}")
404-
import traceback
406+
logger.exception("[installer][android-sdk] sdkmanager error: %s", e)
405407
traceback.print_exc()
406408
return False
407409

@@ -411,14 +413,14 @@ async def _accept_licenses(sdk_root: Path) -> bool:
411413
try:
412414
sdkmanager = _find_sdkmanager(sdk_root)
413415
if not sdkmanager:
414-
print("[installer][android-sdk] sdkmanager not found")
416+
logger.info("[installer][android-sdk] sdkmanager not found")
415417
return False
416418

417419
import asyncio
418420
import subprocess
419421

420422
cmd = [str(sdkmanager), f"--sdk_root={sdk_root}", "--licenses"]
421-
print(f"[installer][android-sdk] Accepting licenses: {' '.join(cmd)}")
423+
logger.info("[installer][android-sdk] Accepting licenses: %s", " ".join(cmd))
422424

423425
if platform.system() == "Windows":
424426
# On Windows, use PowerShell to pipe 'y' responses
@@ -470,25 +472,24 @@ async def _accept_licenses(sdk_root: Path) -> bool:
470472
returncode = result.returncode
471473

472474
if returncode != 0:
473-
print(f"[installer][android-sdk] License acceptance failed: {output}")
475+
logger.error("[installer][android-sdk] License acceptance failed: %s", output)
474476
return False
475-
print("[installer][android-sdk] Licenses accepted successfully")
477+
logger.info("[installer][android-sdk] Licenses accepted successfully")
476478
return True
477479
except Exception as e:
478-
print(f"[installer][android-sdk] License acceptance error: {e}")
479-
import traceback
480+
logger.exception("[installer][android-sdk] License acceptance error: %s", e)
480481
traceback.print_exc()
481482
return False
482483

483484

484485

485486

486487
async def install() -> bool:
487-
print("[installer][android-sdk] Installing...")
488+
logger.info("[installer][android-sdk] Installing...")
488489

489490
# Check if Android SDK is already installed
490491
if await check_status():
491-
print("[installer][android-sdk] Android SDK is already installed")
492+
logger.info("[installer][android-sdk] Android SDK is already installed")
492493
return True
493494

494495
sdk_root = _get_sdk_root()
@@ -520,7 +521,7 @@ async def install() -> bool:
520521
}
521522
})
522523
if not await _accept_licenses(sdk_root):
523-
print("[installer][android-sdk] License acceptance failed")
524+
logger.warning("[installer][android-sdk] License acceptance failed")
524525
# Continue; some environments prompt-less acceptance may not be required
525526

526527

@@ -542,15 +543,15 @@ async def install() -> bool:
542543
}
543544
})
544545
if not await _run_sdkmanager(sdk_root, core_components):
545-
print("[installer][android-sdk] Failed installing one or more SDK components")
546+
logger.error("[installer][android-sdk] Failed installing one or more SDK components")
546547
return False
547548

548549

549550
# Update PATH after successful installation
550551
update_android_sdk_path()
551552

552553

553-
print(f"[installer][android-sdk] Installation successful at {sdk_root}")
554+
logger.info("[installer][android-sdk] Installation successful at %s", sdk_root)
554555
await send_response({
555556
"action": "status",
556557
"data": {

0 commit comments

Comments
 (0)