class Adb: def __init__(self, host='127.0.0.1', port=5037): self.client = PPADBClient(host, port) def connect_to_device(self, host='127.0.0.1', port=5555): adb_path = resource_path(FilePaths.ADB_EXE_PATH.value) cmd = build_command(adb_path, 'connect', "{}:{}".format(host, port)) ret = subprocess.check_output(cmd, shell=True, stderr=subprocess.PIPE, encoding="utf-8", timeout=2) return self.get_device(host, port) def get_client_devices(self): return self.client.devices() def get_device(self, host='127.0.0.1', port=5555): device = self.client.device('{}:{}'.format(host, port)) try: if device is None: self.connect_to_device(host, port) device = self.client.device('{}:{}'.format(host, port)) except Exception as e: traceback.print_exc() return None return device
class adb(): def __init__(self, path: str) -> None: self.path = path ## self.adb_exe = '{}\\platform-tools\\adb.exe'.format(self.path) def connect_to_BS(self, ip: str, port: int) -> None: ''' 待測試 => 重開機直接執行 ''' self.client = AdbClient(host="127.0.0.1", port=5037) try: self.client.remote_connect(ip, port) except: subprocess.Popen('{} start-server'.format(self.adb_exe), stdout=subprocess.PIPE).stdout.read() print('Connect success!') def list_devices(self) -> None: devices = self.client.devices() print('List of devices attached:') for device in devices: print(' {}'.format(device.serial)) def tap(self, device, x: str, y: str) -> None: device.shell('input tap {} {}'.format(x, y)) def get_device(self, serial: str): return self.client.device(serial) def screencap(self, device): image_bytes = device.screencap() img = cv2.imdecode(np.frombuffer(image_bytes, dtype='uint8'), cv2.IMREAD_COLOR) return img
def connect(deviceid): try: cnx = initmysql() cursor = mysqlCursor(cnx) query = execQuery( cursor, "SELECT port,name FROM lords.devices where id=" + str(deviceid)) field_name = [field[0] for field in query.description] result_set = query.fetchone() if result_set != None: row = dict(zip(field_name, result_set)) portNo = int(row['port']) emulatorname = row['name'] else: portNo = 5037 print("name ", emulatorname) adb = Client(host='127.0.0.1', port=portNo) devices = adb.devices() if len(devices) == 0: print('no device attached') quit() device = adb.device(emulatorname) return device except (): quit()
def start_server(self): """ Start ADB server """ try: _adb_kill_server() _adb_start_server() client = AdbClient(host=self._host, port=self._port) if (self._serial or "") == "": devices = client.devices() if len(devices) == 1: self.device = devices[0] elif len(devices) > 1: raise DeviceNotProvidedException() else: raise DeviceNotFoundException() else: self.device = client.device(self._serial) self.state = ADBServerState.OPENED logger.debug("ADB server started successfully.") except Exception as ex: _adb_kill_server() logger.debug("ADB server has failed to start.") self.state = ADBServerState.CLOSED raise ex
def stager_clean(devicename): """ This function cleans the file system by removing the stager binaries created in adb_stager_process """ logging.info("[+] Clean the stager process") client = AdbClient(host="127.0.0.1", port=5037) device = client.device(devicename) device.shell("rm /data/local/tmp/load.sh /data/local/tmp/STAGER")
def main(): with open('/opt/tachiyomimangaexporter/secrets.json') as json_file2: secrets = json.load(json_file2) client = AdbClient(host="127.0.0.1", port=5037) # print(client.version()) ip = conectar(secrets) client.remote_connect(ip, 5555) device = client.device(ip + ":5555") device.pull("/storage/emulated/0/Tachiyomi", "/media/cristian/Datos/Comics/Tachiyomi")
def download(self, id): client = AdbClient(host="127.0.0.1", port=5037) device = client.device(id) url = self.te_link.toPlainText() device.shell("input tap 65.2 411.1") sleep(3) device.shell("input tap 310.2 73") device.input_text(str(url)) device.shell("input keyevent 66") sleep(8) device.shell('input tap 603.7 153.2')
def connect(self, UserPort): client = AdbClient(host="127.0.0.1", port=5037) device = client.device("127.0.0.1:" + UserPort) if device is None: # print("找不到模擬器") self.isConnect = False sys.exit("找不到模擬器") else: # print("找到模擬器") self.device = device self.isConnect = True
class Device: def __init__(self, gjdb): self.path_base = str(Path("C:/01_Works/game-jackyer/server/res/")) self.res_path = str(Path("C:/01_Works/game-jackyer/server/res/img/")) self.default_screen_file = str(Path("C:/01_Works/game-jackyer/server/res/tmp/screen.png")) self.devconfig = list(gjdb['devices'].find()) os.system("adb kill-server") os.system("adb devices") self.client = AdbClient(host="127.0.0.1", port=5037) self.device = self.client.device(self.devconfig[0]["serial"]) self.dscreen_png = cv2.imread(self.default_screen_file) self.dscreen_png = cv2.imencode('.png',self.dscreen_png)[1] self.dscreen_png = self.dscreen_png.tostring() self.screen = None self.screen_png = None self.rlock = threading.RLock() t = threading.Thread(target=self.screen_monitor) t.start() def screen_monitor(self): while True: self.frame() def default_screen(self): return self.dscreen_png def get_screen(self): with self.rlock: return self.screen_png, self.screen def frame(self): screen = self.device.screencap() screen = np.asarray(bytearray(screen), dtype="uint8") screen = cv2.imdecode(screen, cv2.IMREAD_COLOR) screen = cv2.resize(screen,(800,480)) screen_png = cv2.imencode('.png',screen)[1] screen_png = screen_png.tostring() with self.rlock: self.screen = screen self.screen_png = screen_png def input(self, type, param): if type == "tap": x = param.split(',')[0] y = param.split(',')[1] self.device.input_tap(x,y)
def adb_connect(self): try: client = AdbClient(host="127.0.0.1", port=5037) self.adb_device = client.device(self.serial) #print(self.adb_device, self.adb_device == None) if self.adb_device == None: self.adb_device = "no serial" self.err = str("Check Your Device!") else: return self.adb_device except Exception as e: self.adb_device = "" self.err = str(e) return self.adb_device
def conecta_android(): client = AdbClient(host="127.0.0.1", port=5037) print(client.version()) os.system('adb kill-server') sleep(1) os.system('adb usb') sleep(1) os.system('adb devices') sleep(1) os.system('adb tcpip 5556') sleep(1) os.system('adb connect "192.168.0.11:5556"') sleep(1) device = client.device("192.168.0.11:5556") device.shell("echo hello world !") return device
def adb_stager_process(load, devicename): """ This method is in charge to launch load.sh in background The script copy /system/bin/sh to /data/local/tmp and attempt to change its owner to root in a loop TODO: specify the device id """ logging.info("[+] Launch the stager process") client = AdbClient(host="127.0.0.1", port=5037) device = client.device(devicename) device.shell(f"echo {load} > /data/local/tmp/load.sh") device.shell("chmod +x /data/local/tmp/load.sh") device.shell("ln -s /system/bin/sh /data/local/tmp/STAGER") # Launch STAGER shell device.shell("/data/local/tmp/STAGER /data/local/tmp/load.sh")
def check_process_is_running(process, pscmd, devicename): """ This function checks if a given process is running (with adb shell 'ps' command) """ client = AdbClient(host="127.0.0.1", port=5037) device = client.device(devicename) if device == None: logging.warning( f'Device name {device} invalid. Check "adb devices" to get valid ones' ) raise Exception( 'Device name invalid. Check "adb devices" to get valid ones') ps = device.shell(pscmd) if process in ps: logging.warning(f"[+] OK. {process} is running") else: logging.warning(f"[+] NOK. It seems like {process} is not running...") logging.warning("[+] Android_Emuroot stopped") exit(1)
def main(n): eventCount = 0 # Default is "127.0.0.1" and 5037 client = AdbClient(host="127.0.0.1", port=5037) device = client.device("emulator-5554") # Screenshot of the homescreen device.shell("input keyevent 3") take_screenshot(device, "home_1") #Install APK installAPK(device) sleep(1) # Launch the installed app device.shell( f"am start -c api.android.intent.LAUNCHER -a api.android.category.MAIN -n {ANDMIN}" ) sleep(1) # Screenshot of AndMin App open take_screenshot(device, "andmin") sleep( 1 ) # Sleep, so that there is time to take the screenshot if the command is delayed device.shell("input keyevent 3") sleep(2) # For accessing the package name of the app that is open # ans = device.shell("dumpsys window windows | grep Focus") # print(ans) # print(ans.split("\n")) # Screenshot of the homescreen take_screenshot(device, "home_2") while eventCount < n: execute_event(eventCount + 1, device) eventCount += 1 device.shell("input keyevent 3") return device
def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the Template switch.""" name = config.get(CONF_NAME) host = config[CONF_HOST] port = config.get(CONF_PORT) adb_host = config.get(CONF_ADB_HOST) adb_port = config.get(CONF_ADB_PORT) try: client = AdbClient(host=adb_host, port=adb_port) _LOGGER.info("adb server %s connected", adb_host) device = client.device(host + ':' + str(port)) _LOGGER.info("adb device %s connected", host + ':' + str(port)) if device == None: _LOGGER.error("There is no android device %s:%s", host, port) return None except: _LOGGER.error("There is no adb server %s:%s", adb_host, adb_port) return None add_entities([Huestream(name, host, device)])
def kernel_version(): """ This function returns the kernel version """ client = AdbClient(host="127.0.0.1", port=5037) device = client.device(options.device) if device == None: logging.warning( f'Device name {options.device} invalid. Check "adb devices" to get valid ones' ) raise Exception( 'Device name invalid. Check "adb devices" to get valid ones') result = device.shell("uname -r") logging.debug(f" kernel_version() : {result}") result = result.split(".") ver = result[0] + "." + result[1] ver = float(ver) offset_selinux = [] # case kernel version is <= 3.10 if ver <= 3.10: offset_to_comm = 0x288 offset_to_parent = 0xe0 offset_selinux.append(0xC0A77548) offset_selinux.append(0xC0A7754C) offset_selinux.append(0xC0A77550) ps_cmd = "ps" # case kernel version is > 3.10 et <=3.18 elif ver > 3.10 and ver <= 3.18: offset_to_comm = 0x444 offset_to_parent = 0xe0 offset_selinux.append(0xC0C4F288) offset_selinux.append(0xC0C4F28C) offset_selinux.append(0xC0C4F280) ps_cmd = "ps -A" else: logging.warning( f"Sorry. Android kernel version {ver} not supported yet") raise NotImplementedError( "Sorry. Android kernel version not supported yet") return ver, offset_to_comm, offset_to_parent, offset_selinux, ps_cmd
def capture_screen(tmp=False): client = AdbClient(host="127.0.0.1", port=5037) device = client.device("emulator-5554") while True: res = device.screencap() now = time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime(time.time())) with open(tmp_file, "wb") as f: f.write(res) f.close() if tmp: pic_file = screen_file else: pic_file = image_path + now + ".png" Image.open(tmp_file).resize((800, 480)).save(pic_file) print(now)
class ADB: def __init__(self): # Default is "127.0.0.1" and 5037 self.client = AdbClient(host="127.0.0.1", port=5037) self.device = self.client.device("emulator-5554") # if not connect to adb server # type `./adb start-server` after `./emulator -avd Pixel_XL_API_23` self.package_name = None def install_apk(self, apk_filepath): print(f"Install {apk_filepath}") self.device.install(apk_filepath, reinstall=True) def list_all_package(self): print(self.device.shell("pm list packages -f")) def start_apk(self, package_name, main_activity): self.package_name = package_name print("Start running APK") command = f"am start -n {package_name}/{main_activity}" self.device.shell(command) def clean(self): # close the app print("Clean the apk") command = f"am force-stop {self.package_name}" self.device.shell(command) # delete the app self.device.uninstall(self.package_name) def init_frida(self): # push frida server self.device.push("frida-server", "/data/local/tmp/frida-server") # change the mod of frida-server self.device.shell("chmod 755 /data/local/tmp/frida-server") # exec frida server background # It might not work, manually needed. self.device.shell("/data/local/tmp/frida-server &")
""" import os import sys from time import sleep from time import time import numpy as np from adbutils import adb from IPython.display import display from matplotlib import pyplot as plt from PIL import Image from ppadb.client import Client as AdbClient client = AdbClient(host="127.0.0.1", port=5037) device = client.device("8AFY0K7DR") def get_screenshot(file_name="test.png"): result = device.screencap() with open(file_name, "wb") as fp: fp.write(result) return file_name def show_screenshot(): display(Image.open(get_screenshot("tmp"))) os.remove("tmp")
class ADBConnect(object): def __init__(self, args): self._args = args self._useadb = args.use_adb self._client = None if self._useadb: try: from ppadb.client import Client as AdbClient except ImportError: try: from adb.client import Client as AdbClient except ImportError: pass self.check_adblib = 'adb.client' in sys.modules or 'ppadb.client' in sys.modules if not self.check_adblib: logger.warning("Could not find pure-python-adb library. If you are not using ADB you can ignore this") self._useadb = False else: self._client = AdbClient( host=self._args.adb_server_ip, port=self._args.adb_server_port) def check_adb_status(self, adb): if not self._useadb: return None try: if self._client.device(adb) is not None: self._client.device(adb).shell('echo checkadb') return True except RuntimeError: logger.exception('MADmin: Exception occurred while checking adb status ({}).', adb) return None def return_adb_devices(self): if not self._useadb: return [] try: return self._client.devices() except Exception as e: logger.exception('MADmin: Exception occurred while getting adb clients: {}.', e) return [] def send_shell_command(self, adb, origin, command): origin_logger = get_origin_logger(logger, origin=origin) try: device = self._client.device(adb) if device is not None: origin_logger.info('MADmin: Using ADB shell command') device.shell(command) return True except Exception as e: origin_logger.exception('MADmin: Exception occurred while sending shell command: {}.', e) return False def make_screenshot(self, adb, origin, extenstion): origin_logger = get_origin_logger(logger, origin=origin) try: device = self._client.device(adb) if device is not None: origin_logger.info('MADmin: Using ADB') result = device.screencap() # TODO: adjust with devicesettings with open(os.path.join(self._args.temp_path, 'screenshot_%s.png' % str(origin)), "wb") as fp: fp.write(result) if extenstion == "jpg": pngtojpg(os.path.join(self._args.temp_path, 'screenshot_%s.png' % str(origin))) return True except Exception as e: origin_logger.exception('MADmin: Exception occurred while making screenshot: {}.', e) return False def make_screenclick(self, adb, origin, position_x, position_y): origin_logger = get_origin_logger(logger, origin=origin) try: device = self._client.device(adb) if device is not None: device.shell("input tap " + str(position_x) + " " + str(position_y)) origin_logger.info('MADMin ADB Click x:{} y:{}', position_x, position_y) time.sleep(1) return True except Exception as e: origin_logger.exception('MADmin: Exception occurred while making screenclick: {}.', e) return False def make_screenswipe(self, adb, origin, position_x, position_y, swipe_x, swipe_y): origin_logger = get_origin_logger(logger, origin=origin) try: device = self._client.device(adb) if device is not None: device.shell("input swipe " + str(position_x) + " " + str(position_y) + " " + str(swipe_x) + " " + str(swipe_y) + " 100") origin_logger.info('MADMin ADB Swipe x:{} y:{} xe:{} ye:{}', position_x, position_y, swipe_x, swipe_y) time.sleep(1) return True except Exception as e: origin_logger.exception('MADmin: Exception occurred while making screenswipe: {}.', e) return False def push_file(self, adb, origin, filename): origin_logger = get_origin_logger(logger, origin=origin) try: device = self._client.device(adb) if device is not None: device.shell("adb push " + str(filename) + " /sdcard/Download") origin_logger.info('MADMin ADB Push File {}', filename) time.sleep(1) return True except Exception as e: origin_logger.exception('MADmin: Exception occurred while pushing file: {}.', e) return False
def testDump(self, window): client = AdbClient(host="127.0.0.1", port=5037) dev = client.devices() dev2 = client.device("YT910815C7") self.outText.delete('1.0', END) self.outText.insert(END, dev2.shell("echo test2"))
class ADBServer(object): """A manager for ADB connections that uses an ADB server. Parameters ---------- host : str The address of the device; may be an IP address or a host name port : int The device port to which we are connecting (default is 5555) adb_server_ip : str The IP address of the ADB server adb_server_port : int The port for the ADB server """ def __init__(self, host, port=5555, adb_server_ip='', adb_server_port=5037): self.host = host self.port = int(port) self.adb_server_ip = adb_server_ip self.adb_server_port = adb_server_port self._adb_client = None self._adb_device = None # keep track of whether the ADB connection is intact self._available = False # use a lock to make sure that ADB commands don't overlap self._adb_lock = threading.Lock() @property def available(self): """Check whether the ADB connection is intact. Returns ------- bool Whether or not the ADB connection is intact """ if not self._adb_client: return False try: # make sure the server is available adb_devices = self._adb_client.devices() # make sure the device is available try: # case 1: the device is currently available host_port = '{}:{}'.format(self.host, self.port) if any( [host_port in dev.get_serial_no() for dev in adb_devices]): if not self._available: self._available = True return True # case 2: the device is not currently available if self._available: _LOGGER.error('ADB server is not connected to the device.') self._available = False return False except RuntimeError: if self._available: _LOGGER.error( 'ADB device is unavailable; encountered an error when searching for device.' ) self._available = False return False except RuntimeError: if self._available: _LOGGER.error('ADB server is unavailable.') self._available = False return False except Exception as exc: # noqa pylint: disable=broad-except if self._available: _LOGGER.error('ADB server is unavailable, error: %s', exc) self._available = False return False def close(self): """Close the ADB server socket connection. Currently, this doesn't do anything. """ def connect(self, always_log_errors=True): """Connect to an Android TV / Fire TV device. Parameters ---------- always_log_errors : bool If True, errors will always be logged; otherwise, errors will only be logged on the first failed reconnect attempt Returns ------- bool Whether or not the connection was successfully established and the device is available """ try: with _acquire(self._adb_lock): # Catch exceptions try: self._adb_client = Client(host=self.adb_server_ip, port=self.adb_server_port) self._adb_device = self._adb_client.device('{}:{}'.format( self.host, self.port)) # ADB connection successfully established if self._adb_device: _LOGGER.debug( "ADB connection to %s:%d via ADB server %s:%d successfully established", self.host, self.port, self.adb_server_ip, self.adb_server_port) self._available = True return True # ADB connection attempt failed (without an exception) if self._available or always_log_errors: _LOGGER.warning( "Couldn't connect to %s:%d via ADB server %s:%d", self.host, self.port, self.adb_server_ip, self.adb_server_port) self.close() self._available = False return False # ADB connection attempt failed except Exception as exc: # noqa pylint: disable=broad-except if self._available or always_log_errors: _LOGGER.warning( "Couldn't connect to %s:%d via ADB server %s:%d, error: %s", self.host, self.port, self.adb_server_ip, self.adb_server_port, exc) self.close() self._available = False return False except LockNotAcquiredException: _LOGGER.warning( "Couldn't connect to %s:%d via ADB server %s:%d because pure-python-adb lock not acquired.", self.host, self.port, self.adb_server_ip, self.adb_server_port) self.close() self._available = False return False def pull(self, local_path, device_path): """Pull a file from the device using an ADB server. Parameters ---------- local_path : str The path where the file will be saved device_path : str The file on the device that will be pulled """ if not self.available: _LOGGER.debug( "ADB command not sent to %s:%d via ADB server %s:%d because pure-python-adb connection is not established: pull(%s, %s)", self.host, self.port, self.adb_server_ip, self.adb_server_port, local_path, device_path) return with _acquire(self._adb_lock): _LOGGER.debug( "Sending command to %s:%d via ADB server %s:%d: pull(%s, %s)", self.host, self.port, self.adb_server_ip, self.adb_server_port, local_path, device_path) self._adb_device.pull(device_path, local_path) return def push(self, local_path, device_path): """Push a file to the device using an ADB server. Parameters ---------- local_path : str The file that will be pushed to the device device_path : str The path where the file will be saved on the device """ if not self.available: _LOGGER.debug( "ADB command not sent to %s:%d via ADB server %s:%d because pure-python-adb connection is not established: push(%s, %s)", self.host, self.port, self.adb_server_ip, self.adb_server_port, local_path, device_path) return with _acquire(self._adb_lock): _LOGGER.debug( "Sending command to %s:%d via ADB server %s:%d: push(%s, %s)", self.host, self.port, self.adb_server_ip, self.adb_server_port, local_path, device_path) self._adb_device.push(local_path, device_path) return def shell(self, cmd): """Send an ADB command using an ADB server. Parameters ---------- cmd : str The ADB command to be sent Returns ------- str, None The response from the device, if there is a response """ if not self._available: _LOGGER.debug( "ADB command not sent to %s:%d via ADB server %s:%d because pure-python-adb connection is not established: %s", self.host, self.port, self.adb_server_ip, self.adb_server_port, cmd) return None with _acquire(self._adb_lock): _LOGGER.debug("Sending command to %s:%d via ADB server %s:%d: %s", self.host, self.port, self.adb_server_ip, self.adb_server_port, cmd) return self._adb_device.shell(cmd)
class FireTV: """Represents an Amazon Fire TV device.""" def __init__(self, host, port=5555, adb_server_ip="127.0.0.1", adb_server_port=5037): """Initialize FireTV object. :param host: Host in format <address>:port. :param adbkey: The path to the "adbkey" file :param adb_server_ip: the IP address for the ADB server :param adb_server_port: the port for the ADB server """ self.host = host self.port = port self.adb_server_port = adb_server_port self.adb_server_ip = adb_server_ip # keep track of whether the ADB connection is intact self._available = False # use a lock to make sure that ADB commands don't overlap self._adb_lock = threading.Lock() # the attributes used for sending ADB commands; filled in in `self.connect()` self._adb = None # python-adb self._adb_client = None # pure-python-adb self._adb_device = None # pure-python-adb && adb_shell # pure-python-adb self.adb_shell = self._adb_shell_pure_python_adb self.adb_streaming_shell = self._adb_streaming_shell_pure_python_adb # establish the ADB connection self.connect() # ======================================================================= # # # # ADB methods # # # # ======================================================================= # def _adb_shell_adb_shell(self, cmd): if not self.available: return None if self._adb_lock.acquire(**LOCK_KWARGS): try: return self._adb_device.shell(cmd) finally: self._adb_lock.release() def _adb_shell_python_adb(self, cmd): if not self.available: return None if self._adb_lock.acquire(**LOCK_KWARGS): try: return self._adb.Shell(cmd) finally: self._adb_lock.release() def _adb_shell_pure_python_adb(self, cmd): if not self._available: return None if self._adb_lock.acquire(**LOCK_KWARGS): try: return self._adb_device.shell(cmd) finally: self._adb_lock.release() def _adb_streaming_shell_adb_shell(self, cmd): if not self.available: return [] if self._adb_lock.acquire(**LOCK_KWARGS): try: return self._adb_device.shell(cmd) finally: self._adb_lock.release() def _adb_streaming_shell_python_adb(self, cmd): if not self.available: return [] if self._adb_lock.acquire(**LOCK_KWARGS): try: return self._adb.StreamingShell(cmd) finally: self._adb_lock.release() def _adb_streaming_shell_pure_python_adb(self, cmd): if not self._available: return None # this is not yet implemented if self._adb_lock.acquire(**LOCK_KWARGS): try: return [] finally: self._adb_lock.release() def _dump(self, service, grep=None): """Perform a service dump. :param service: Service to dump. :param grep: Grep for this string. :returns: Dump, optionally grepped. """ if grep: return self.adb_shell('dumpsys {0} | grep "{1}"'.format( service, grep)) return self.adb_shell('dumpsys {0}'.format(service)) def _dump_has(self, service, grep, search): """Check if a dump has particular content. :param service: Service to dump. :param grep: Grep for this string. :param search: Check for this substring. :returns: Found or not. """ dump_grep = self._dump(service, grep=grep) if not dump_grep: return False return dump_grep.strip().find(search) > -1 def _key(self, key): """Send a key event to device. :param key: Key constant. """ self.adb_shell('input keyevent {0}'.format(key)) def _keyboard(self, literal): """Send text to device :param key: text string to send. """ self.adb_shell(f'input text "{literal}"') def _ps(self, search=''): """Perform a ps command with optional filtering. :param search: Check for this substring. :returns: List of matching fields """ if not self.available: return result = [] ps = self.adb_streaming_shell('ps') try: for bad_line in ps: # The splitting of the StreamingShell doesn't always work # this is to ensure that we get only one line for line in bad_line.splitlines(): if search in line: result.append(line.strip().rsplit(' ', 1)[-1]) return result except InvalidChecksumError as e: print(e) self.connect() raise IOError def _send_intent(self, pkg, intent, count=1): cmd = 'monkey -p {} -c {} {}; echo $?'.format(pkg, intent, count) logging.debug("Sending an intent %s to %s (count: %s)", intent, pkg, count) # adb shell outputs in weird format, so we cut it into lines, # separate the retcode and return info to the user res = self.adb_shell(cmd) if res is None: return {} res = res.strip().split("\r\n") retcode = res[-1] output = "\n".join(res[:-1]) return {"retcode": retcode, "output": output} def connect(self, always_log_errors=True): """Connect to an Amazon Fire TV device. Will attempt to establish ADB connection to the given host. Failure sets state to UNKNOWN and disables sending actions. :returns: True if successful, False otherwise """ self._adb_lock.acquire(**LOCK_KWARGS) try: # pure-python-adb try: self._adb_client = AdbClient() self._adb_client.remote_connect(self.host, self.port) print(self._adb_client.devices()) self._adb_device = self._adb_client.device( f"{self.host}:{self.port}") self._available = bool(self._adb_device) except: traceback.print_exc() self._available = False finally: return self._available finally: self._adb_lock.release() # ======================================================================= # # # # Home Assistant Update # # # # ======================================================================= # def update(self, get_running_apps=True): """Get the state of the device, the current app, and the running apps. :param get_running_apps: whether or not to get the ``running_apps`` property :return state: the state of the device :return current_app: the current app :return running_apps: the running apps """ # The `screen_on`, `awake`, `wake_lock_size`, `current_app`, and `running_apps` properties. screen_on, awake, wake_lock_size, _current_app, running_apps = self.get_properties( get_running_apps=get_running_apps, lazy=True) # Check if device is off. if not screen_on: state = STATE_OFF current_app = None running_apps = None # Check if screen saver is on. elif not awake: state = STATE_IDLE current_app = None running_apps = None else: # Get the current app. if isinstance(_current_app, dict) and 'package' in _current_app: current_app = _current_app['package'] else: current_app = None # Get the running apps. if running_apps is None and current_app: running_apps = [current_app] # Get the state. # TODO: determine the state differently based on the `current_app`. if current_app in [PACKAGE_LAUNCHER, PACKAGE_SETTINGS]: state = STATE_STANDBY # Amazon Video elif current_app == AMAZON_VIDEO: if wake_lock_size == 5: state = STATE_PLAYING else: # wake_lock_size == 2 state = STATE_PAUSED # Netflix elif current_app == NETFLIX: if wake_lock_size > 3: state = STATE_PLAYING else: state = STATE_PAUSED # Check if `wake_lock_size` is 1 (device is playing). elif wake_lock_size == 1: state = STATE_PLAYING # Otherwise, device is paused. else: state = STATE_PAUSED return state, current_app, running_apps # ======================================================================= # # # # App methods # # # # ======================================================================= # def app_state(self, app): """Informs if application is running.""" if not self.available or not self.screen_on: return STATE_OFF if self.current_app["package"] == app: return STATE_ON return STATE_OFF def launch_app(self, app): """Launch an app.""" return self._send_intent(app, INTENT_LAUNCH) def stop_app(self, app): """Stop an app.""" return self.adb_shell("am force-stop {0}".format(app)) # ======================================================================= # # # # properties # # # # ======================================================================= # @property def state(self): """Compute and return the device state. :returns: Device state. """ # Check if device is disconnected. if not self.available: return STATE_UNKNOWN # Check if device is off. if not self.screen_on: return STATE_OFF # Check if screen saver is on. if not self.awake: return STATE_IDLE # Check if the launcher is active. if self.launcher or self.settings: return STATE_STANDBY # Check for a wake lock (device is playing). if self.wake_lock: return STATE_PLAYING # Otherwise, device is paused. return STATE_PAUSED @property def available(self): """Check whether the ADB connection is intact.""" if USE_ADB_SHELL: # adb_shell if not self._adb_device: return False return self._adb_device.available if not self.adb_server_ip: # python-adb return bool(self._adb) # pure-python-adb try: # make sure the server is available adb_devices = self._adb_client.devices() # make sure the device is available try: # case 1: the device is currently available if any( [self.host in dev.get_serial_no() for dev in adb_devices]): if not self._available: self._available = True return True # case 2: the device is not currently available if self._available: logging.error('ADB server is not connected to the device.') self._available = False return False except RuntimeError: if self._available: logging.error( 'ADB device is unavailable; encountered an error when searching for device.' ) self._available = False return False except RuntimeError: if self._available: logging.error('ADB server is unavailable.') self._available = False return False @property def running_apps(self): """Return a list of running user applications.""" ps = self.adb_shell(RUNNING_APPS_CMD) if ps: return [ line.strip().rsplit(' ', 1)[-1] for line in ps.splitlines() if line.strip() ] return [] @property def current_app(self): """Return the current app.""" current_focus = self.adb_shell(CURRENT_APP_CMD) if current_focus is None: return None current_focus = current_focus.replace("\r", "") matches = WINDOW_REGEX.search(current_focus) # case 1: current app was successfully found if matches: (pkg, activity) = matches.group("package", "activity") return {"package": pkg, "activity": activity} # case 2: current app could not be found logging.warning("Couldn't get current app, reply was %s", current_focus) return None @property def screen_on(self): """Check if the screen is on.""" return self.adb_shell(SCREEN_ON_CMD + SUCCESS1_FAILURE0) == '1' @property def awake(self): """Check if the device is awake (screensaver is not running).""" return self.adb_shell(AWAKE_CMD + SUCCESS1_FAILURE0) == '1' @property def wake_lock(self): """Check for wake locks (device is playing).""" return self.adb_shell(WAKE_LOCK_CMD + SUCCESS1_FAILURE0) == '1' @property def wake_lock_size(self): """Get the size of the current wake lock.""" output = self.adb_shell(WAKE_LOCK_SIZE_CMD) if not output: return None return int(output.split("=")[1].strip()) @property def launcher(self): """Check if the active application is the Amazon TV launcher.""" return self.current_app["package"] == PACKAGE_LAUNCHER @property def settings(self): """Check if the active application is the Amazon menu.""" return self.current_app["package"] == PACKAGE_SETTINGS def get_properties(self, get_running_apps=True, lazy=False): """Get the ``screen_on``, ``awake``, ``wake_lock_size``, ``current_app``, and ``running_apps`` properties.""" if get_running_apps: output = self.adb_shell(SCREEN_ON_CMD + (SUCCESS1 if lazy else SUCCESS1_FAILURE0) + " && " + AWAKE_CMD + (SUCCESS1 if lazy else SUCCESS1_FAILURE0) + " && " + WAKE_LOCK_SIZE_CMD + " && " + CURRENT_APP_CMD + " && " + RUNNING_APPS_CMD) else: output = self.adb_shell(SCREEN_ON_CMD + (SUCCESS1 if lazy else SUCCESS1_FAILURE0) + " && " + AWAKE_CMD + (SUCCESS1 if lazy else SUCCESS1_FAILURE0) + " && " + WAKE_LOCK_SIZE_CMD + " && " + CURRENT_APP_CMD) # ADB command was unsuccessful if output is None: return None, None, None, None, None # `screen_on` property if not output: return False, False, -1, None, None screen_on = output[0] == '1' # `awake` property if len(output) < 2: return screen_on, False, -1, None, None awake = output[1] == '1' lines = output.strip().splitlines() # `wake_lock_size` property if len(lines[0]) < 3: return screen_on, awake, -1, None, None wake_lock_size = int(lines[0].split("=")[1].strip()) # `current_app` property if len(lines) < 2: return screen_on, awake, wake_lock_size, None, None matches = WINDOW_REGEX.search(lines[1]) if matches: # case 1: current app was successfully found (pkg, activity) = matches.group("package", "activity") current_app = {"package": pkg, "activity": activity} else: # case 2: current app could not be found current_app = None # `running_apps` property if not get_running_apps or len(lines) < 3: return screen_on, awake, wake_lock_size, current_app, None running_apps = [ line.strip().rsplit(' ', 1)[-1] for line in lines[2:] if line.strip() ] return screen_on, awake, wake_lock_size, current_app, running_apps # ======================================================================= # # # # turn on/off methods # # # # ======================================================================= # def turn_on(self): """Send power action if device is off.""" self.adb_shell(SCREEN_ON_CMD + " || (input keyevent {0} && input keyevent {1})".format( POWER, HOME)) def turn_off(self): """Send power action if device is not off.""" self.adb_shell(SCREEN_ON_CMD + " && input keyevent {0}".format(SLEEP)) # ======================================================================= # # # # "key" methods: basic commands # # # # ======================================================================= # def backspace(self): """Send backspace action.""" self._key(DELETE) def search(self): """Send search action.""" self._key(SEARCH) def info(self): """Send info action.""" self._key(INFO) def power(self): """Send power action.""" self._key(POWER) def sleep(self): """Send sleep action.""" self._key(SLEEP) def home(self): """Send home action.""" self._key(HOME) def up(self): """Send up action.""" self._key(UP) def down(self): """Send down action.""" self._key(DOWN) def left(self): """Send left action.""" self._key(LEFT) def right(self): """Send right action.""" self._key(RIGHT) def enter(self): """Send enter action.""" self._key(ENTER) def back(self): """Send back action.""" self._key(BACK) def menu(self): """Send menu action.""" self._key(MENU) def volume_up(self): """Send volume up action.""" self._key(VOLUME_UP) def volume_down(self): """Send volume down action.""" self._key(VOLUME_DOWN) def grave(self): """Send backtick action.""" self._key(GRAVE) def settings(self): """Send settings action.""" self._key(SETTINGS) def backslash(self): """Send backslash action.""" self._key(BACKSLASH) # ======================================================================= # # # # "key" methods: media commands # # # # ======================================================================= # def media_play_pause(self): """Send media play/pause action.""" self._key(PLAY_PAUSE) def media_play(self): """Send media play action.""" self._key(PLAY) def media_pause(self): """Send media pause action.""" self._key(PAUSE) def media_next(self): """Send media next action (results in fast-forward).""" self._key(NEXT) def media_previous(self): """Send media previous action (results in rewind).""" self._key(PREVIOUS) def media_fast_forward(self): """Send media fast forward action.""" self._key(FAST_FORWARD) def media_rewind(self): """Send media rewind action.""" self._key(REWIND) def media_skip_backwards(self): """Send media skip backward action.""" self._key(SKIP_BACKWARD) # ======================================================================= # # # # "key" methods: key commands # # # # ======================================================================= # def keyboard(self, literal): """Send keyboard literal keypress.""" self._keyboard(literal)
logger = logging.getLogger() if verbose_level > 0: logger.addHandler(create_console_handler(verbose_level)) logger.setLevel(logging.DEBUG) # Connecting on local adb server try: client = AdbClient(host="127.0.0.1", port=5037) except: logger.error("Unable to connect to adb server") logger.error( "Please check your configuration and run ``adb start-server''") sys.exit(1) if len(client.devices()) < 2: logger.error("This program needs 2 phones connected with ADB") # instanciate 2 pogo games dev_id1 = client.device(config['app1']['device_id']) dev_id1.name = 'app1' dev_id2 = client.device(config['app2']['device_id']) dev_id2.name = 'app2' # trading p = Pool(2) for trade in range(args.stop_after): logger.warning("Trade num {}/{} engaged".format( str(trade + 1), str(args.stop_after))) if not do_trade(trade, p): sys.exit(0)
from ppadb.client import Client as AdbClient client = AdbClient(host="127.0.0.1", port=5037) device = client.device("emulator-5554") def takeScreenshot(): result = device.screencap() with open("images/screen.png", "wb") as fp: fp.write(result) def tap(x, y): device.shell(f'input touchscreen tap {y} {x}') def swipe(x, y): device.shell(f'input touchscreen swipe {y} {x} {y} {x} 250') def text(text): device.shell(f'input text {text}')
from ppadb.client import Client def dump_logcat_by_line(connect): file_obj = connect.socket.makefile() while True: print("Line: {}".format(file_obj.readline().strip())) file_obj.close() connect.close() client = Client() device = client.device("4c9a5ecc") device.shell("logcat", handler=dump_logcat_by_line)
os.system('adb -e shell input keyevent 62') if event.type == KEYDOWN: if event.key == K_EXCLAIM: os.system('adb -e shell input keyevent 207') if event.type == KEYDOWN: if event.key == K_LEFTPAREN: os.system('adb -e shell input keyevent 162') if event.type == KEYDOWN: if event.key == K_RIGHTPAREN: os.system('adb -e shell input keyevent 163') if event.type == KEYDOWN: if event.key == K_MINUS: os.system('adb -e shell input keyevent 89') if event.type == KEYDOWN: if event.key == K_PLUS: os.system('adb -e shell input keyevent 81') if event.type == MOUSEBUTTONDOWN: mousepos = pygame.mouse.get_pos() mousepos = str(mousepos[0]) + ' ' + str(mousepos[1]) print (f"input tap {mousepos}") device.shell(f"input tap {mousepos}") client = AdbClient(host="127.0.0.1", port=5037) device = client.device(f"{dev}") result = device.screencap() img = pygame.image.load(io.BytesIO(result)) #img = pygame.transform.scale(img, (640, 960)) screen.blit(img, (0, 0)) clock.tick(20) pygame.display.flip()
class UsbConnector(object): def __init__(self): self.connected = False self._client: AdbClient = None self.my_device: Device = None self._host = '127.0.0.1' self._port = 5037 self.connectionChangedFunctions = [] self.checkingConnectionFunctions = [] self.connectionCheckThread = WorkerThread() self._continousCheckStopRequired = False self._startConnectionCheck() def _changeConnectedState(self, c): if self.connected != c: self.connected = c for f in self.connectionChangedFunctions: f() def checkingConnectionChange(self, state: bool): for f in self.checkingConnectionFunctions: f(state) def stopConnectionCheck(self): print("Stopping continous device check") self._continousCheckStopRequired = True def setFunctionToCallOnConnectionStateChanged(self, function): if function not in self.connectionChangedFunctions: self.connectionChangedFunctions.append(function) def setFunctionToCallOnCheckingConnectionStateChanged(self, function): if function not in self.checkingConnectionFunctions: self.checkingConnectionFunctions.append(function) def getDeviceSerialNo(self): try: device = os.popen("adb devices").read().split('\n', 1)[1].split("device")[0].strip() device = None if device == '' else device return device except: return None # def checkDeviceAvailable(self): # # try: # # device = os.popen("adb devices").read().split('\n', 1)[1].split("device")[0].strip() # # device = None if device == '' else device # # return device != '' and device != None # # except: # # return False def tryConnect(self) -> bool: # Default is "127.0.0.1" and 5037, but nox is 62001 if self.connected and self.getDeviceSerialNo() is not None: return True self._changeConnectedState(False) self.checkingConnectionChange(True) ports = [5037, 62001] ok = False os.system("adb disconnect") dev = 'device' for p in ports: os.system("adb connect {}:{}".format(self._host, p)) dev = self.getDeviceSerialNo() if dev is not None: if 'offline' not in dev: self._port = 5037 ok = True break os.system("adb disconnect") if ok: self._client = AdbClient(host=self._host, port=self._port) self.my_device = self._client.device(dev) self._changeConnectedState(True) else: self._changeConnectedState(False) self.checkingConnectionChange(False) return self.connected def disconnect(self) -> bool: if not self.connected: return True self.my_device = None self._client = None self._changeConnectedState(False) return True def _get_device_id(self) -> str: if not self.connected: return '' return self.my_device.get_serial_no() def adb_get_size(self) -> tuple: if not self.connected: return 0, 0 bytes_screen = self.my_device.screencap() im = Image.open(io.BytesIO(bytes_screen)) w, h = im.size im.close() return w, h def adb_screen(self, name: str = "screen.png") -> bool: if not self.connected: return False """ Executes a screen and saved it in current folder as 'screen.png' :return: """ os.system("adb exec-out screencap -p > " + name) return True def adb_screen_getpixels(self): if not self.connected: return np.zeros((1080, 2220)) bytes_screen = self.my_device.screencap() with Image.open(io.BytesIO(bytes_screen)) as im: pixval = np.array(im.getdata()) return pixval def adb_swipe(self, locations, s) -> bool: if not self.connected: return False """ Executes sdb swipe function Parameters: locations (array(int), size=4): [x1,y1,x2,y2] coords duration (int): duration (seconds) """ s = int(s * 1000) x1, y1, x2, y2 = locations[0], locations[1], locations[2], locations[3] self.my_device.input_swipe(int(x1), int(y1), int(x2), int(y2), s) return True def adb_tap(self, coord) -> bool: if not self.connected: return False """ Executes sdb tap function Parameters: coord (tuple(x, y)): coordinate of tap """ x, y = coord[0], coord[1] self.my_device.input_tap(int(x), int(y)) return True keycodes = { "KEYCODE_UNKNOWN": 0, "KEYCODE_MENU": 1, "KEYCODE_SOFT_RIGHT": 2, "KEYCODE_HOME": 3, "KEYCODE_BACK": 4, "KEYCODE_CALL": 5, "KEYCODE_ENDCALL": 6, "KEYCODE_0": 7, "KEYCODE_1": 8, "KEYCODE_2": 9, "KEYCODE_3": 10, "KEYCODE_4": 11, "KEYCODE_5": 12, "KEYCODE_6": 13, "KEYCODE_7": 14, "KEYCODE_8": 15, "KEYCODE_9": 16, "KEYCODE_STAR": 17, "KEYCODE_POUND": 18, "KEYCODE_DPAD_UP": 19, "KEYCODE_DPAD_DOWN": 20, "KEYCODE_DPAD_LEFT": 21, "KEYCODE_DPAD_RIGHT": 22, "KEYCODE_DPAD_CENTER": 23, "KEYCODE_VOLUME_UP": 24, "KEYCODE_VOLUME_DOWN": 25, "KEYCODE_POWER": 26, "KEYCODE_CAMERA": 27, "KEYCODE_CLEAR": 28, "KEYCODE_A": 29, "KEYCODE_B": 30, "KEYCODE_C": 31, "KEYCODE_D": 32, "KEYCODE_E": 33, "KEYCODE_F": 34, "KEYCODE_G": 35, "KEYCODE_H": 36, "KEYCODE_I": 37, "KEYCODE_J": 38, "KEYCODE_K": 39, "KEYCODE_L": 40, "KEYCODE_M": 41, "KEYCODE_N": 42, "KEYCODE_O": 43, "KEYCODE_P": 44, "KEYCODE_Q": 45, "KEYCODE_R": 46, "KEYCODE_S": 47, "KEYCODE_T": 48, "KEYCODE_U": 49, "KEYCODE_V": 50, "KEYCODE_W": 51, "KEYCODE_X": 52, "KEYCODE_Y": 53, "KEYCODE_Z": 54, "KEYCODE_COMMA": 55, "KEYCODE_PERIOD": 56, "KEYCODE_ALT_LEFT": 57, "KEYCODE_ALT_RIGHT": 58, "KEYCODE_SHIFT_LEFT": 59, "KEYCODE_SHIFT_RIGHT": 60, "KEYCODE_TAB": 61, "KEYCODE_SPACE": 62, "KEYCODE_SYM": 63, "KEYCODE_EXPLORER": 64, "KEYCODE_ENVELOPE": 65, "KEYCODE_ENTER": 66, "KEYCODE_DEL": 67, "KEYCODE_GRAVE": 68, "KEYCODE_MINUS": 69, "KEYCODE_EQUALS": 70, "KEYCODE_LEFT_BRACKET": 71, "KEYCODE_RIGHT_BRACKET": 72, "KEYCODE_BACKSLASH": 73, "KEYCODE_SEMICOLON": 74, "KEYCODE_APOSTROPHE": 75, "KEYCODE_SLASH": 76, "KEYCODE_AT": 77, "KEYCODE_NUM": 78, "KEYCODE_HEADSETHOOK": 79, "KEYCODE_FOCUS": 80, "KEYCODE_PLUS": 81, "KEYCODE_MENU_2": 82, "KEYCODE_NOTIFICATION": 83, "KEYCODE_SEARCH": 84, "TAG_LAST_KEYCODE": 85, } def adb_tap_key(self, keycode: str) -> bool: if not self.connected: return False if keycode in self.keycodes: self.my_device.input_keyevent(self.keycodes[keycode]) else: return False return True def _oneCheck(self): time.sleep(1) while True: if self._continousCheckStopRequired: break c = self.tryConnect() if c != self.connected: if self.connected: self.disconnect() else: self._changeConnectedState(True) # self.connect() changed into tryConnect time.sleep(5) def _startConnectionCheck(self): self._continousCheckStopRequired = False self.connectionCheckThread.function = self._oneCheck self.connectionCheckThread.start()
def get_device(): client = Client(host='127.0.0.1', port=5037) device = client.device('127.0.0.1:62001') return device
from os.path import basename, join import os from ppadb.client import Client as AdbClient # Questo percorso deve essere accessibile da non-root: DEF_PATH = "/storage/emulated/0" LIST = [] RESULT = -1 local_path = '/tmp/transf' if len(sys.argv) == 2 else sys.argv[2] print("Retrieving files...") # Default is "127.0.0.1" and 5037 client = AdbClient(host="127.0.0.1", port=5037) device = client.device("ZX1G22NQG3") # Nexus def make_list(conn): global LIST data = conn.socket.makefile().read() LIST = data.split("\n") l = 1 def get(basedir, lpath): global RESULT, l, clean_up device.shell("su -C \"ls -F {} | tr -d '\\r'\"".format(basedir),