* Added "Recheck for connected device feature" * WIP on progress bar

working for larger transfers * More generated debug files that I will
  probably use to help create tests
This commit is contained in:
2025-08-25 11:18:48 -05:00
committed by Jason Ross
parent ffba056153
commit 7df056ef60
20 changed files with 1895 additions and 24 deletions
+110 -8
View File
@@ -1,26 +1,128 @@
"""
Debug script for troubleshooting ADB device detection issues.
This script provides comprehensive debugging information for ADB connectivity,
including binary path verification, device detection, and command execution testing.
Debug large transfer ADB output
"""
import os
import sys
import subprocess
import re
import time
import os
# Add the src directory to Python path for imports
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), "src"))
from adb_manager import ADBManager
from adb_manager import ADB_BINARY_PATH
def debug_large_transfer_output():
"""Debug what ADB output looks like for large transfers."""
print("=== DEBUGGING LARGE TRANSFER ADB OUTPUT ===")
print("This will show you what ADB actually outputs during large transfers.")
print("Use Ctrl+C to stop when you see enough output.\n")
# Get user input for paths
remote_path = input("Enter remote path (e.g., /sdcard/DCIM): ").strip()
if not remote_path:
remote_path = "/sdcard/DCIM"
local_path = input("Enter local path (e.g., C:\\temp\\debug_transfer): ").strip()
if not local_path:
local_path = "C:\\temp\\debug_transfer"
print(f"\nDebugging transfer: {remote_path} -> {local_path}")
print("ADB output analysis:\n")
cmd = [ADB_BINARY_PATH, "pull", remote_path, local_path]
try:
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1,
)
line_count = 0
progress_lines = []
if proc.stdout:
for line in proc.stdout:
line_count += 1
line_clean = line.strip()
# Check for progress information
progress_match = re.search(r"\((\d{1,3})%\)", line)
# Log interesting lines
if (
progress_match
or "%" in line
or line_count <= 20
or line_count % 100 == 0
):
print(f"Line {line_count:4d}: {line_clean}")
if progress_match:
pct = int(progress_match.group(1))
progress_lines.append((line_count, pct, line_clean))
# Show periodic updates for very long transfers
if line_count % 500 == 0:
print(f"... ({line_count} lines processed) ...")
proc.wait()
print(f"\n=== TRANSFER COMPLETED ===")
print(f"Total lines: {line_count}")
print(f"Return code: {proc.returncode}")
print(f"Progress lines found: {len(progress_lines)}")
if progress_lines:
print("\nProgress line analysis:")
for line_num, pct, text in progress_lines:
print(f" Line {line_num}: {pct}% - {text}")
else:
print("No explicit progress percentages found in output!")
print("This explains why large transfers don't show progress.")
except KeyboardInterrupt:
print(f"\n\nStopped at line {line_count}")
if proc:
proc.terminate()
if progress_lines:
print(f"Progress lines found so far: {len(progress_lines)}")
for line_num, pct, text in progress_lines[-5:]: # Show last 5
print(f" Line {line_num}: {pct}% - {text}")
except Exception as e:
print(f"Error: {e}")
def main():
"""Run comprehensive ADB debugging tests."""
"""Debug large transfer functionality."""
print("Choose debug option:")
print("1. Debug large transfer ADB output")
print("2. Run original ADB detection tests")
choice = input("Enter choice (1 or 2): ").strip()
if choice == "1":
debug_large_transfer_output()
else:
debug_original_adb_detection()
def debug_original_adb_detection():
"""Original ADB debugging functionality."""
from adb_manager import ADBManager
print("=== ADB Device Detection Debug ===\n")
# Test 1: Check if ADB binary exists
adb_manager = ADBManager()
from adb_manager import ADB_BINARY_PATH
adb_path = ADB_BINARY_PATH
print(f"1. ADB Binary Path: {adb_path}")
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env python3
"""
Debug version of main window with console output
"""
import sys
sys.path.insert(0, "src")
from gui.main_window import AndroidFileHandlerGUI
class DebugAndroidFileHandlerGUI(AndroidFileHandlerGUI):
"""Debug version with console output."""
def _initialize_components(self):
"""Initialize GUI components and handlers with debug output."""
super()._initialize_components()
# Wrap the progress callback with debug output
original_update_progress = self.progress_handler.update_progress
def debug_update_progress(percentage):
print(f"DEBUG: Progress update called with {percentage}%")
return original_update_progress(percentage)
# Wrap the status callback with debug output
original_set_status = self.progress_handler.set_status
def debug_set_status(message):
print(f"DEBUG: Status update called with '{message}'")
return original_set_status(message)
# Replace the callbacks
self.progress_handler.update_progress = debug_update_progress
self.progress_handler.set_status = debug_set_status
# Update ADB manager callbacks
self.adb_manager.set_progress_callback(self.progress_handler.update_progress)
self.adb_manager.set_status_callback(self.progress_handler.set_status)
print("DEBUG: Callbacks set up with debug wrappers")
def main():
"""Main function to run the debug application."""
if sys.platform not in ["win32", "linux"]:
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.withdraw()
messagebox.showerror(
"Unsupported OS", "This application only supports Windows or Linux."
)
sys.exit(1)
app = DebugAndroidFileHandlerGUI()
app.mainloop()
if __name__ == "__main__":
main()
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env python3
"""
Debug folder name parsing from ADB ls output
"""
import sys
import subprocess
sys.path.insert(0, "src")
from adb_manager import ADB_BINARY_PATH
def debug_folder_parsing():
"""Debug folder name parsing from ls -la output."""
print("=== DEBUGGING FOLDER NAME PARSING ===")
print("This will show actual ADB ls output and how it's parsed.\n")
path = input("Enter Android path to list (e.g., /sdcard): ").strip()
if not path:
path = "/sdcard"
print(f"Running: adb shell ls -la '{path}'\n")
try:
cmd = [ADB_BINARY_PATH, "shell", "ls", "-la", path]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
print(f"Return code: {result.returncode}")
print(f"Raw output:\n{repr(result.stdout)}")
print(f"Error output: {repr(result.stderr)}")
print("\n" + "=" * 50)
print("PARSED OUTPUT:")
print("=" * 50)
if result.stdout and result.stdout.strip():
lines = result.stdout.strip().split("\n")
print(f"Total lines: {len(lines)}\n")
for i, line in enumerate(lines):
print(f"Line {i+1}: {repr(line)}")
if line.startswith("d"):
# Current parsing logic
parts = line.split()
print(f" Parts ({len(parts)}): {parts}")
if len(parts) >= 8:
current_name = " ".join(parts[7:])
print(f" Current parsing result: '{current_name}'")
# Improved parsing - try different approaches
# Method 1: Find the last occurrence of time pattern and take everything after
import re
time_pattern = r"\d{2}:\d{2}"
time_match = list(re.finditer(time_pattern, line))
if time_match:
last_time = time_match[-1]
improved_name = line[last_time.end() :].strip()
print(f" Improved parsing result: '{improved_name}'")
if improved_name != current_name:
print(f" *** DIFFERENCE DETECTED! ***")
# Method 2: Manual field parsing (more reliable)
# drwxrwxrwx root root 2024-01-01 12:00 folder_name
tokens = line.split()
if len(tokens) >= 6:
# Skip permissions, links, user, group, size, date, time
# Take everything from index 8 (or find after time pattern)
manual_name = (
" ".join(tokens[8:])
if len(tokens) > 8
else (tokens[7] if len(tokens) == 8 else "")
)
print(f" Manual parsing result: '{manual_name}'")
else:
print(
f" *** NOT ENOUGH PARTS! Expected >= 8, got {len(parts)}"
)
print()
else:
print("No output received!")
except subprocess.TimeoutExpired:
print("Command timed out!")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
debug_folder_parsing()
+104
View File
@@ -0,0 +1,104 @@
#!/usr/bin/env python3
"""
Test improved progress calculation for large transfers
"""
import sys
import time
import threading
sys.path.insert(0, "src")
from gui.main_window import AndroidFileHandlerGUI
def test_large_transfer_progress():
"""Test improved progress calculation."""
class TestApp(AndroidFileHandlerGUI):
def __init__(self):
super().__init__()
self.progress_updates = []
# Capture progress updates
original_update = self.progress_handler.update_progress
def capture_progress(percentage):
self.progress_updates.append((time.time(), percentage))
print(f"Progress: {percentage}%")
return original_update(percentage)
self.progress_handler.update_progress = capture_progress
self.adb_manager.set_progress_callback(
self.progress_handler.update_progress
)
app = TestApp()
def simulate_large_transfer():
"""Simulate a large transfer with many output lines."""
time.sleep(1)
print("=== Testing Large Transfer Progress ===")
# Simulate the internal progress logic without actual ADB
start_time = time.time()
last_update_time = start_time
last_progress = 0
print("Simulating 2000 lines of output (like a large transfer)...")
for line_count in range(1, 2001):
current_time = time.time()
# Simulate the improved progress logic
elapsed_time = current_time - start_time
time_since_last_update = current_time - last_update_time
should_update = False
new_progress = last_progress
# Time-based progress (update every 2 seconds)
if time_since_last_update >= 2.0 and last_progress < 95:
if line_count > 100:
activity_factor = min(line_count / 1000, 50)
time_factor = min(elapsed_time / 60, 40)
new_progress = min(activity_factor + time_factor, 95)
else:
new_progress = min(last_progress + 10, 95)
should_update = True
# Line-based progress
elif line_count % 50 == 0 and last_progress < 90:
increment = max(1, min(5, 90 // (line_count // 50 + 1)))
new_progress = min(last_progress + increment, 90)
should_update = True
if should_update and new_progress > last_progress:
app.adb_manager._update_progress(int(new_progress))
last_progress = new_progress
last_update_time = current_time
# Speed up simulation
if line_count % 100 == 0:
time.sleep(0.1)
# Complete the transfer
app.adb_manager._update_progress(100)
print(f"\nTotal progress updates: {len(app.progress_updates)}")
print("Progress timeline:")
start_time = app.progress_updates[0][0] if app.progress_updates else time.time()
for timestamp, percentage in app.progress_updates[-10:]: # Show last 10
elapsed = timestamp - start_time
print(f" {elapsed:.1f}s: {percentage}%")
threading.Thread(target=simulate_large_transfer, daemon=True).start()
# Run for limited time
app.after(15000, app.destroy) # Close after 15 seconds
app.mainloop()
if __name__ == "__main__":
test_large_transfer_progress()
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""
Minimal test to verify progress updates work in modular GUI
"""
import sys
import time
import threading
sys.path.insert(0, "src")
from gui.main_window import AndroidFileHandlerGUI
def test_minimal_progress():
"""Test minimal progress updates."""
print("Creating GUI...")
app = AndroidFileHandlerGUI()
def test_updates():
time.sleep(1) # Wait for GUI to be ready
print("Starting test updates...")
# Test direct progress handler calls
print("Testing progress handler directly...")
app.progress_handler.update_progress(25)
time.sleep(0.5)
app.progress_handler.update_progress(50)
time.sleep(0.5)
app.progress_handler.update_progress(75)
time.sleep(0.5)
app.progress_handler.update_progress(100)
time.sleep(1)
# Test ADB manager calls (should go through callbacks)
print("Testing through ADB manager...")
app.adb_manager._update_progress(0)
time.sleep(0.5)
app.adb_manager._update_progress(30)
time.sleep(0.5)
app.adb_manager._update_progress(60)
time.sleep(0.5)
app.adb_manager._update_progress(90)
time.sleep(0.5)
app.adb_manager._update_progress(100)
print("Test completed!")
# Start test in background
threading.Thread(target=test_updates, daemon=True).start()
# Run GUI
print("Starting GUI mainloop...")
app.mainloop()
if __name__ == "__main__":
test_minimal_progress()
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env python3
"""
Debug test for progress callback in modular GUI
"""
import sys
import os
sys.path.insert(0, "src")
from gui.main_window import AndroidFileHandlerGUI
def test_callbacks():
"""Test if callbacks are being set properly."""
app = AndroidFileHandlerGUI()
print("Testing callback setup...")
print(f"ADB Manager progress callback: {app.adb_manager.progress_callback}")
print(f"ADB Manager status callback: {app.adb_manager.status_callback}")
print(f"Progress handler: {app.progress_handler}")
print(
f"Progress handler update_progress method: {app.progress_handler.update_progress}"
)
print(f"Progress handler set_status method: {app.progress_handler.set_status}")
# Test direct call
print("\nTesting direct progress update...")
app.progress_handler.update_progress(50)
app.update()
print("\nTesting direct status update...")
app.progress_handler.set_status("Testing status")
app.update()
print(
"\nTest completed. Check if progress bar shows 50% and status shows 'Testing status'"
)
app.mainloop()
if __name__ == "__main__":
test_callbacks()
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""
Test successive transfers with modular GUI
"""
import sys
import time
import threading
sys.path.insert(0, "src")
from gui.main_window import AndroidFileHandlerGUI
def simulate_transfer(app, transfer_name):
"""Simulate a transfer with progress updates."""
print(f"Starting {transfer_name}")
app.progress_handler.set_status(f"Starting {transfer_name}...")
app.progress_handler.reset_progress()
# Simulate progress updates
for i in range(0, 101, 10):
time.sleep(0.1) # Simulate work
app.progress_handler.update_progress(i)
app.progress_handler.set_status(f"{transfer_name}: {i}% complete")
app.progress_handler.set_status(f"{transfer_name} completed!")
print(f"Completed {transfer_name}")
def test_successive_transfers():
"""Test successive transfers to ensure progress bar works correctly."""
app = AndroidFileHandlerGUI()
def run_transfers():
time.sleep(1) # Wait for GUI to be ready
simulate_transfer(app, "Transfer 1")
time.sleep(0.5)
simulate_transfer(app, "Transfer 2")
time.sleep(0.5)
simulate_transfer(app, "Transfer 3")
print("All transfers completed!")
# Start transfers in background thread
threading.Thread(target=run_transfers, daemon=True).start()
app.mainloop()
if __name__ == "__main__":
test_successive_transfers()
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
"""
Debug test following normal application flow
"""
import sys
import os
import time
import threading
sys.path.insert(0, "src")
from gui.main_window import AndroidFileHandlerGUI
def test_normal_flow():
"""Test following the normal application flow exactly."""
app = AndroidFileHandlerGUI()
def debug_transfer():
# Wait for app to initialize
time.sleep(2)
print("=== DEBUGGING NORMAL APPLICATION FLOW ===")
print(f"App ADB manager: {app.adb_manager}")
print(f"App progress handler: {app.progress_handler}")
print(f"ADB manager progress callback: {app.adb_manager.progress_callback}")
print(f"ADB manager status callback: {app.adb_manager.status_callback}")
# Set up a test transfer
app.remote_path_var.set("/sdcard/Download")
app.local_path_var.set(r"C:\temp")
print("\n=== SIMULATING START TRANSFER BUTTON CLICK ===")
# Check if local path exists
if not os.path.exists(r"C:\temp"):
os.makedirs(r"C:\temp", exist_ok=True)
# Test the exact method that gets called
app.current_transfer_id += 1
transfer_id = app.current_transfer_id
print(f"Transfer ID: {transfer_id}")
app.disable_controls()
app.progress_handler.reset_progress()
print("\n=== TESTING PROGRESS UPDATES DIRECTLY ===")
app.adb_manager._update_progress(25)
app.update()
time.sleep(0.5)
app.adb_manager._update_progress(50)
app.update()
time.sleep(0.5)
app.adb_manager._update_progress(75)
app.update()
time.sleep(0.5)
app.adb_manager._update_progress(100)
app.update()
print("=== PROGRESS UPDATES COMPLETED ===")
app.enable_controls()
# Start debug in background
threading.Thread(target=debug_transfer, daemon=True).start()
app.mainloop()
if __name__ == "__main__":
test_normal_flow()
+67
View File
@@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""
Test real transfer workflow
"""
import sys
import os
import time
import threading
sys.path.insert(0, "src")
from gui.main_window import AndroidFileHandlerGUI
def test_real_transfer_workflow():
"""Test the real transfer workflow with console output."""
# Add debug output to see what's happening
class DebugApp(AndroidFileHandlerGUI):
def __init__(self):
super().__init__()
# Wrap callbacks with debug output
original_progress = self.adb_manager.progress_callback
original_status = self.adb_manager.status_callback
def debug_progress(percentage):
print(f"PROGRESS: {percentage}%")
if original_progress:
original_progress(percentage)
def debug_status(message):
print(f"STATUS: {message}")
if original_status:
original_status(message)
self.adb_manager.set_progress_callback(debug_progress)
self.adb_manager.set_status_callback(debug_status)
app = DebugApp()
def simulate_transfer():
time.sleep(2) # Wait for app to be ready
print("=== SIMULATING BUTTON CLICK ===")
# Set up paths (use a path that doesn't exist to avoid actual transfer)
app.remote_path_var.set("/nonexistent/path")
app.local_path_var.set(r"C:\temp")
# Create temp dir if needed
os.makedirs(r"C:\temp", exist_ok=True)
# Call start_transfer method directly
print("Calling start_transfer()...")
app.start_transfer()
# Start simulation
threading.Thread(target=simulate_transfer, daemon=True).start()
print("Starting app...")
app.mainloop()
if __name__ == "__main__":
test_real_transfer_workflow()