import subprocess import time import sys import os from datetime import datetime class AirplaneModeController: def __init__(self): self.adb_path = self.find_adb() def find_adb(self): """Find ADB executable path""" possible_paths = [ 'adb', # System PATH '/data/data/com.termux/files/usr/bin/adb', # Termux '/system/bin/adb', # Android system 'platform-tools/adb', # Local folder ] for path in possible_paths: try: result = subprocess.run([path, 'version'], capture_output=True, timeout=3) if result.returncode == 0: print(f"✅ Found ADB at: {path}") return path except (FileNotFoundError, subprocess.TimeoutExpired): continue print("❌ ADB not found!") print("💡 Install with: pkg install android-tools") sys.exit(1) def check_connection(self): """Check if ADB is connected to device""" try: result = subprocess.run([self.adb_path, 'devices'], capture_output=True, text=True, timeout=5) devices = result.stdout.strip().split(' ')[1:] # Skip header connected_devices = [d for d in devices if d.strip() and 'device' in d] if not connected_devices: print("❌ No devices connected!") print("💡 Make sure LADB server is running") return False print(f"✅ Connected to: {connected_devices[0]}") return True except Exception as e: print(f"❌ Connection check failed: {e}") return False def get_airplane_state(self): """Get current airplane mode state""" try: result = subprocess.run( [self.adb_path, 'shell', 'settings', 'get', 'global', 'airplane_mode_on'], capture_output=True, text=True, timeout=5 ) state = result.stdout.strip() return state == '1' except Exception as e: print(f"âš ī¸ Could not get state: {e}") return None def set_airplane_mode(self, enable): """Set airplane mode with enhanced error handling""" state = '1' if enable else '0' mode_text = "ON" if enable else "OFF" timestamp = datetime.now().strftime("%H:%M:%S") try: # Method 1: Standard settings command result1 = subprocess.run( [self.adb_path, 'shell', 'settings', 'put', 'global', 'airplane_mode_on', state], capture_output=True, text=True, timeout=10 ) if result1.returncode != 0: print(f"âš ī¸ Settings command failed: {result1.stderr}") return False # Method 2: Broadcast intent (trigger UI update) result2 = subprocess.run( [self.adb_path, 'shell', 'am', 'broadcast', '-a', 'android.intent.action.AIRPLANE_MODE', '--ez', 'state', str(enable).lower()], capture_output=True, text=True, timeout=10 ) # Verify the change time.sleep(0.5) actual_state = self.get_airplane_state() if actual_state == enable: print(f"[{timestamp}] ✅ Airplane mode is {mode_text}") return True else: print(f"[{timestamp}] âš ī¸ State mismatch! Expected: {enable}, Got: {actual_state}") return False except subprocess.TimeoutExpired: print(f"❌ Command timed out") return False except Exception as e: print(f"❌ Error: {e}") return False def toggle_once(self, on_duration=5, off_duration=5): """Toggle airplane mode once""" print(f" {'='*50}") print(f"🔄 Starting single toggle cycle") print(f" ON: {on_duration}s | OFF: {off_duration}s") print(f"{'='*50} ") # Turn ON if self.set_airplane_mode(True): print(f"âŗ Waiting {on_duration} seconds...") time.sleep(on_duration) else: print("❌ Failed to turn ON") return False # Turn OFF if self.set_airplane_mode(False): print(f"âŗ Waiting {off_duration} seconds...") time.sleep(off_duration) else: print("❌ Failed to turn OFF") return False return True def toggle_loop(self, on_duration=5, off_duration=10, cycles=None): """Toggle in a loop with customizable cycles""" cycle_count = 0 failed_attempts = 0 max_failures = 3 print(f" {'='*50}") print(f"🚀 Starting airplane mode loop") print(f" ON: {on_duration}s | OFF: {off_duration}s") print(f" Cycles: {'∞ Infinite' if cycles is None else cycles}") print(f"{'='*50} ") try: while cycles is None or cycle_count < cycles: cycle_count += 1 print(f" 📍 Cycle #{cycle_count}") print("-" * 30) # Turn ON if not self.set_airplane_mode(True): failed_attempts += 1 if failed_attempts >= max_failures: print(f" ❌ Too many failures ({max_failures}). Stopping.") break continue time.sleep(on_duration) # Turn OFF if not self.set_airplane_mode(False): failed_attempts += 1 if failed_attempts >= max_failures: print(f" ❌ Too many failures ({max_failures}). Stopping.") break continue failed_attempts = 0 # Reset on success time.sleep(off_duration) except KeyboardInterrupt: print(" âšī¸ Stopped by user (Ctrl+C)") finally: print(" 🔄 Ensuring airplane mode is OFF...") self.set_airplane_mode(False) print(" ✅ Script finished ") def main(): """Main function with menu""" print(" " + "="*50) print("âœˆī¸ AIRPLANE MODE CONTROLLER") print("="*50 + " ") controller = AirplaneModeController() # Check ADB connection if not controller.check_connection(): print(" 💡 TROUBLESHOOTING:") print("1. Open LADB app") print("2. Tap 'Start ADB Server'") print("3. Wait for 'ADB is running' message") print("4. Run this script again ") sys.exit(1) # Check current state current = controller.get_airplane_state() if current is not None: print(f"📱 Current state: {'ON âœˆī¸' if current else 'OFF đŸ“ļ'} ") # Menu print("Choose mode:") print("1. Toggle once (5s ON, 5s OFF)") print("2. Loop 10 times (5s ON, 10s OFF)") print("3. Infinite loop (5s ON, 10s OFF)") print("4. Custom settings") print("5. Exit") choice = input(" Enter choice (1-5): ").strip() if choice == '1': controller.toggle_once(on_duration=5, off_duration=5) elif choice == '2': controller.toggle_loop(on_duration=5, off_duration=10, cycles=10) elif choice == '3': controller.toggle_loop(on_duration=5, off_duration=10, cycles=None) elif choice == '4': try: on_time = int(input("Seconds ON: ")) off_time = int(input("Seconds OFF: ")) cycles_input = input("Number of cycles (press Enter for infinite): ").strip() cycles = int(cycles_input) if cycles_input else None controller.toggle_loop(on_duration=on_time, off_duration=off_time, cycles=cycles) except ValueError: print("❌ Invalid input") elif choice == '5': print("👋 Goodbye!") else: print("❌ Invalid choice") if __name__ == "__main__": main()