| | import os |
| | import subprocess |
| | import time |
| | from flask import Flask, request, jsonify |
| |
|
| |
|
| | def list_all_devices(): |
| | adb_command = "adb devices" |
| | device_list = [] |
| | result = EmulatorController.execute_adb(adb_command) |
| | if result != "ERROR": |
| | devices = result.split("\n")[1:] |
| | for d in devices: |
| | device_list.append(d.split()[0]) |
| |
|
| | return device_list |
| |
|
| | def get_adb_device_name(avd_name=None): |
| | device_list = list_all_devices() |
| | for device in device_list: |
| | command = f"adb -s {device} emu avd name" |
| | ret = EmulatorController.execute_adb(command) |
| | ret = ret.split("\n")[0] |
| | if ret == avd_name: |
| | return device |
| | return None |
| |
|
| |
|
| | app = Flask(__name__) |
| |
|
| | class Config: |
| | avd_log_dir = "/logs" |
| |
|
| | class EmulatorController: |
| | def __init__(self): |
| | self.avd_log_dir = "logs" |
| | self.emulator_process = None |
| | self.out_file = None |
| | |
| | @classmethod |
| | def execute_adb(self, adb_command): |
| | print(f"Executing command: {adb_command}") |
| | assert adb_command.startswith("adb"), "Command must start with 'adb'" |
| | adb_command = "/root/.android/platform-tools/adb" + adb_command[3:] |
| |
|
| | result = subprocess.run(adb_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) |
| | print(f"Return code: {result}") |
| | if result.returncode == 0: |
| | return result.stdout.strip() |
| | print(f"Command execution failed: {adb_command}") |
| | print(result.stderr) |
| | return "ERROR" |
| | |
| | def start_emulator(self, avd_name): |
| | print(f"Starting Android Emulator with AVD name: {avd_name}") |
| | |
| | if not os.path.exists(self.avd_log_dir): |
| | os.makedirs(self.avd_log_dir, exist_ok=True) |
| | |
| | self.out_file = open(os.path.join(self.avd_log_dir, 'emulator_output.txt'), 'a') |
| | |
| | self.emulator_process = subprocess.Popen( |
| | ["/root/.android/emulator/emulator", "-avd", avd_name, "-no-snapshot-save", "-no-window", "-no-audio"], |
| | stdout=self.out_file, |
| | stderr=self.out_file |
| | ) |
| | |
| | print("Waiting for the emulator to start...") |
| | |
| | while True: |
| | time.sleep(1) |
| | try: |
| | device = get_adb_device_name(avd_name) |
| | except: |
| | import traceback |
| | traceback.print_exc() |
| | continue |
| | if device is not None: |
| | break |
| | |
| | print("Device name: ", device) |
| | print("AVD name: ", avd_name) |
| | |
| | while True: |
| | boot_complete = f"adb -s {device} shell getprop init.svc.bootanim" |
| | boot_complete = self.execute_adb(boot_complete) |
| | if boot_complete == 'stopped': |
| | print("Emulator started successfully") |
| | break |
| | time.sleep(1) |
| | |
| | time.sleep(1) |
| | |
| | device_list = list_all_devices() |
| | if len(device_list) == 1: |
| | device = device_list[0] |
| | print(f"Device selected: {device}") |
| | |
| | return device |
| |
|
| | def stop_emulator(self, avd_name): |
| | print("Stopping Android Emulator...") |
| | if self.emulator_process: |
| | self.emulator_process.terminate() |
| | |
| | while True: |
| | try: |
| | device = get_adb_device_name(avd_name) |
| | command = f"adb -s {device} reboot -p" |
| | ret = self.execute_adb(command) |
| | self.emulator_process.terminate() |
| | except: |
| | device = None |
| | if device is None: |
| | print("Emulator stopped successfully") |
| | break |
| | time.sleep(1) |
| | |
| | if self.out_file: |
| | self.out_file.close() |
| |
|
| | emulator_controller = EmulatorController() |
| |
|
| | @app.route('/start', methods=['POST']) |
| | def start(): |
| | avd_name = request.json.get('avd_name') |
| | if not avd_name: |
| | return jsonify({"error": "No AVD name provided"}), 400 |
| |
|
| | device = emulator_controller.start_emulator(avd_name) |
| | return jsonify({"result": "Emulator started", "device": device}) |
| |
|
| | @app.route('/stop', methods=['POST']) |
| | def stop(): |
| | avd_name = request.json.get('avd_name') |
| | if not avd_name: |
| | return jsonify({"error": "No AVD name provided"}), 400 |
| |
|
| | emulator_controller.stop_emulator(avd_name) |
| | return jsonify({"result": "Emulator stopped"}) |
| |
|
| | @app.route('/execute', methods=['POST']) |
| | def execute(): |
| | adb_command = request.json.get('command') |
| | if not adb_command: |
| | return jsonify({"error": "No command provided"}), 400 |
| |
|
| | result = emulator_controller.execute_adb(adb_command) |
| | return jsonify({"result": result}) |
| |
|
| | if __name__ == '__main__': |
| | app.run(host='0.0.0.0', port=6060) |
| |
|