def _nc_server_host_port(self): """ Returns: str, int, str, int: server_listen_host, server_listen_port, client_connect_host, client_connect_port """ # For BlueStacks hyper-v, use ADB reverse if self.is_bluestacks_hyperv: host = '127.0.0.1' logger.info(f'Connecting to BlueStacks hyper-v, using host {host}') port = self.adb_reverse(f'tcp:{self.config.REVERSE_SERVER_PORT}') return host, port, host, self.config.REVERSE_SERVER_PORT # For emulators, listen on current host if self.is_emulator or self.is_over_http: host = socket.gethostbyname(socket.gethostname()) if platform.system() == 'Linux' and host == '127.0.1.1': host = '127.0.0.1' logger.info(f'Connecting to local emulator, using host {host}') port = random_port(self.config.FORWARD_PORT_RANGE) # For AVD instance if self.is_avd: return host, port, "10.0.2.2", port return host, port, host, port # For local network devices, listen on the host under the same network as target device if self.is_network_device: hosts = socket.gethostbyname_ex(socket.gethostname())[2] logger.info(f'Current hosts: {hosts}') ip = ipaddress.ip_address(self.serial.split(':')[0]) for host in hosts: if ip in ipaddress.ip_interface(f'{host}/24').network: logger.info( f'Connecting to local network device, using host {host}' ) port = random_port(self.config.FORWARD_PORT_RANGE) return host, port, host, port # For other devices, create an ADB reverse and listen on 127.0.0.1 host = '127.0.0.1' logger.info(f'Connecting to unknown device, using host {host}') port = self.adb_reverse(f'tcp:{self.config.REVERSE_SERVER_PORT}') return host, port, host, self.config.REVERSE_SERVER_PORT
def adb_reverse(self, remote): port = 0 for reverse in self.adb.reverse_list(): if reverse.remote == remote and reverse.local.startswith('tcp:'): if not port: logger.info(f'Reuse reverse: {reverse}') port = int(reverse.local[4:]) else: logger.info(f'Remove redundant forward: {reverse}') self.adb_forward_remove(reverse.local) if port: return port else: # Create new reverse port = random_port(self.config.FORWARD_PORT_RANGE) reverse = ReverseItem(f'tcp:{port}', remote) logger.info(f'Create reverse: {reverse}') self.adb.reverse(reverse.local, reverse.remote) return port
def adb_forward(self, remote): """ Do `adb forward <local> <remote>`. choose a random port in FORWARD_PORT_RANGE or reuse an existing forward, and also remove redundant forwards. Args: remote (str): tcp:<port> localabstract:<unix domain socket name> localreserved:<unix domain socket name> localfilesystem:<unix domain socket name> dev:<character device name> jdwp:<process pid> (remote only) Returns: int: Port """ port = 0 for forward in self.adb.forward_list(): if forward.serial == self.serial and forward.remote == remote and forward.local.startswith( 'tcp:'): if not port: logger.info(f'Reuse forward: {forward}') port = int(forward.local[4:]) else: logger.info(f'Remove redundant forward: {forward}') self.adb_forward_remove(forward.local) if port: return port else: # Create new forward port = random_port(self.config.FORWARD_PORT_RANGE) forward = ForwardItem(self.serial, f'tcp:{port}', remote) logger.info(f'Create forward: {forward}') self.adb.forward(forward.local, forward.remote) return port