def _setup_stream_server(self, lazy=False): """ Setup minicap process on device Args: lazy: parameter `-l` is used when True Returns: adb shell process, non-blocking stream reader and local port """ localport, deviceport = self.adb.setup_forward("localabstract:minicap_{}".format) deviceport = deviceport[len("localabstract:"):] other_opt = "-l" if lazy else "" params, display_info = self._get_params() proc = self.adb.start_shell( "%s -n '%s' -P %dx%d@%dx%d/%d %s 2>&1" % tuple([self.CMD, deviceport] + list(params) + [other_opt]), ) nbsp = NonBlockingStreamReader(proc.stdout, print_output=True, name="minicap_server") while True: line = nbsp.readline(timeout=5.0) if line is None: raise RuntimeError("minicap server setup timeout") if b"Server start" in line: break if proc.poll() is not None: # minicap server setup error, may be already setup by others # subprocess exit immediately raise RuntimeError("minicap server quit immediately") reg_cleanup(proc.kill) self._stream_rotation = int(display_info["rotation"]) return proc, nbsp, localport
def __init__(self, adb): self.adb = adb self.ow_proc = None self.ow_callback = [] self._t = None self.current_orientation = None reg_cleanup(self.teardown)
def __init__(self, iosHandle): self.iosHandle = iosHandle self.ow_callback = [] self.roundProcess = None self._stopEvent = threading.Event() self.last_result = None reg_cleanup(self.teardown)
def _setup_stream_server(self): """ Setup stream server Returns: adb shell process, non-blocking stream reader and local port """ localport, deviceport = self.adb.setup_forward( "localabstract:javacap_{}".format) deviceport = deviceport[len("localabstract:"):] # setup agent proc apkpath = self.adb.path_app(self.APP_PKG) cmds = [ "CLASSPATH=" + apkpath, 'exec', 'app_process', '/system/bin', self.SCREENCAP_SERVICE, "--scale", "100", "--socket", "%s" % deviceport, "-lazy", "2>&1" ] proc = self.adb.start_shell(cmds) # check proc output nbsp = NonBlockingStreamReader(proc.stdout, print_output=True, name="javacap_sever", auto_kill=True) while True: line = nbsp.readline(timeout=5.0) if line is None: raise ScreenError("javacap server setup timeout") if b"Capture server listening on" in line: break if b"Address already in use" in line: raise ScreenError("javacap server setup error: %s" % line) reg_cleanup(kill_proc, proc) return proc, nbsp, localport
def __init__(self, adb, backend=False): self.adb = adb self.backend = backend self.server_proc = None self.client = None self.display_info = None self.max_x, self.max_y = None, None reg_cleanup(self.teardown)
def __init__(self, adb, backend=False, ori_function=None): self.adb = adb self.backend = backend self.server_proc = None self.client = None self.size_info = None self.ori_function = ori_function if callable(ori_function) else self.adb.getPhysicalDisplayInfo self.max_x, self.max_y = None, None reg_cleanup(self.teardown)
def __init__(self, uuid=None): self.subprocessHandle = [] # uuid不是ios手机序列号,而是wda.info['uuid']字段 self.uuid = uuid # 下面_udid这个是真正的手机序列号,检测到是USB设备,才会记录这个字段 self._udid = None self._device = None self.cleanup_handler = [] reg_cleanup(self.tear_down)
def __init__(self, uuid=None): self.subprocessHandle = [] # uuid不是ios手机序列号,而是wda.info['uuid']字段 self.uuid = uuid # 下面_udid这个是真正的手机序列号,检测到是USB设备,才会记录这个字段 self._udid = None self._device = None # 记录曾经使用过的端口号和关闭端口用的方法,方便后续释放端口, _port_using_func[port] = kill_func self._port_using_func = {} reg_cleanup(self.tear_down)
def __init__(self, adb, projection=None): """ :param adb: adb instance of android device :param projection: projection, default is None. If `None`, physical display size is used """ self.adb = adb self.projection = projection self.frame_gen = None self.stream_lock = threading.Lock() self.quirk_flag = 0 reg_cleanup(self.teardown_stream)
def __init__(self, adb, ori_method=ORI_METHOD.MINICAP): self.adb = adb self.ow_proc = None self.nbsp = None self.ow_callback = [] self.ori_method = ori_method self._t = None self._t_kill_event = threading.Event() self.current_orientation = None self.path_in_android = "/data/local/tmp/" + os.path.basename(ROTATIONWATCHER_JAR) reg_cleanup(self.teardown)
def __init__(self, adb, backend=False, size_info=None, input_event=None, *args, **kwargs): self.adb = adb self.backend = backend self.server_proc = None self.client = None self.size_info = None self.input_event = input_event self.handle = None self.size_info = size_info or self.adb.get_display_info() self.default_pressure = 50 self.path_in_android = "" reg_cleanup(self.teardown)
def __init__(self, adb, backend=False, ori_function=None, input_event=None): self.adb = adb self.backend = backend self.server_proc = None self.client = None self.size_info = None self.input_event = input_event self.handle = None self.ori_function = ori_function if callable(ori_function) else self.adb.getPhysicalDisplayInfo self.default_pressure = 50 self.path_in_android = "" reg_cleanup(self.teardown)
def setup_server(self): """ Setup minitouch server and adb forward Returns: server process """ if self.server_proc: self.server_proc.kill() self.server_proc = None self.localport, deviceport = self.adb.setup_forward( "localabstract:minitouch_{}".format) deviceport = deviceport[len("localabstract:"):] if self.input_event: p = self.adb.start_shell( "/data/local/tmp/minitouch -n '{0}' -d '{1}' 2>&1".format( deviceport, self.input_event)) else: p = self.adb.start_shell( "/data/local/tmp/minitouch -n '{0}' 2>&1".format(deviceport)) nbsp = NonBlockingStreamReader(p.stdout, name="minitouch_server", auto_kill=True) while True: line = nbsp.readline(timeout=3.0) if line is None: kill_proc(p) self.adb.close_proc_pipe(p) raise RuntimeError("minitouch setup timeout") line = line.decode(get_std_encoding(sys.stdout)) # 识别出setup成功的log,并匹配出max_x, max_y m = re.search( "Type \w touch device .+ \((\d+)x(\d+) with \d+ contacts\) detected on .+ \(.+\)", line) if m: self.max_x, self.max_y = int(m.group(1)), int(m.group(2)) break else: self.max_x = 32768 self.max_y = 32768 # nbsp.kill() # 保留,不杀了,后面还会继续读取并pirnt if p.poll() is not None: # server setup error, may be already setup by others # subprocess exit immediately kill_proc(p) raise RuntimeError("minitouch server quit immediately") self.server_proc = p reg_cleanup(kill_proc, self.server_proc) return p
def start_recording(self, max_time=1800, bit_rate=None): """ Start screen recording Args: max_time: maximum screen recording time, default is 1800 bit_rate: bit rate value, 450000-8000000, default is None(6000000) Raises: RuntimeError: if any error occurs while setup the recording Returns: None if recording did not start, otherwise True """ if getattr(self, "recording_proc", None): raise AirtestError("recording_proc has already started") pkg_path = self.adb.path_app(YOSEMITE_PACKAGE) max_time_param = "-Dduration=%d" % max_time if max_time else "" # The higher the bitrate, the clearer the video, the default value is 6000000 bit_rate_param = "-Dbitrate=%d" % bit_rate if bit_rate else "" # The video size is square, compatible with horizontal and vertical screens p = self.adb.start_shell( 'CLASSPATH=%s exec app_process %s %s /system/bin %s.Recorder --start-record' % (pkg_path, max_time_param, bit_rate_param, YOSEMITE_PACKAGE)) nbsp = NonBlockingStreamReader(p.stdout, name="start_recording_" + str(id(self))) # 进程p必须要保留到stop_recording执行时、或是退出前才进行清理,否则会导致录屏进程提前终止 reg_cleanup(kill_proc, p) while True: line = nbsp.readline(timeout=5) if line is None: nbsp.kill() kill_proc(p) raise RuntimeError("start recording error") if six.PY3: line = line.decode("utf-8") # 如果上次录屏被强制中断,可能会导致无法开始下一次录屏,额外发一个停止录屏指令 if re.search("Record has already started", line): self.stop_recording(is_interrupted=True) continue m = re.match( "start result: Record start success! File path:(.*\.mp4)", line.strip()) if m: output = m.group(1) self.recording_proc = p self.recording_file = output nbsp.kill() return True
def setup(self): cmd = [self.executable, "--udid", self.udid, "--port", str(self.port), "--resolution", self.resolution] print(cmd) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE) reg_cleanup(proc.kill) nbsp = NonBlockingStreamReader(proc.stdout, print_output=True, name="minicap_sever") while True: line = nbsp.readline(timeout=10.0) if line is None: raise RuntimeError("minicap setup error") if b"== Banner ==" in line: break if proc.poll() is not None: logging.warn("Minicap server already started, use old one") self.server_proc = proc
def get_frames(self): """ Get the screen frames Returns: None """ proc, nbsp, localport = self._setup_stream_server() s = SafeSocket() s.connect((self.adb.host, localport)) try: t = s.recv(24) except Exception as e: # 在部分手机上,可能连接可以成功建立,但是在开始获取数据时会报错 raise ScreenError(e) # javacap header LOGGING.debug(struct.unpack("<2B5I2B", t)) stopping = False reg_cleanup(s.close) while not stopping: s.send(b"1") # recv frame header, count frame_size if self.RECVTIMEOUT is not None: header = s.recv_with_timeout(4, self.RECVTIMEOUT) else: header = s.recv(4) if header is None: LOGGING.error("javacap header is None") # recv timeout, if not frame updated, maybe screen locked stopping = yield None else: frame_size = struct.unpack("<I", header)[0] frame_data = s.recv(frame_size) stopping = yield frame_data LOGGING.debug("javacap stream ends") s.close() nbsp.kill() kill_proc(proc) self.adb.remove_forward("tcp:%s" % localport)
def _install_and_setup(self): """ Install and setup the RotationWatcher package Raises: RuntimeError: if any error occurs while installing the package Returns: None """ try: apk_path = self.adb.path_app(ROTATIONWATCHER_PACKAGE) except AirtestError: self.adb.install_app(ROTATIONWATCHER_APK, ROTATIONWATCHER_PACKAGE) apk_path = self.adb.path_app(ROTATIONWATCHER_PACKAGE) p = self.adb.start_shell('export CLASSPATH=%s;exec app_process /system/bin jp.co.cyberagent.stf.rotationwatcher.RotationWatcher' % apk_path) if p.poll() is not None: raise RuntimeError("orientationWatcher setup error") self.ow_proc = p reg_cleanup(self.ow_proc.kill)
def _get_subnet_mask_len(self): """ Perform `adb shell netcfg | grep wlan0` command to obtain mask length Returns: 17 if mask length could not be detected, otherwise the mask length """ try: res = self.shell('netcfg') except AdbShellError: pass else: matcher = re.search(r'wlan0.* (\d+\.){3}\d+/(\d+) ', res) if matcher: return int(matcher.group(2)) # 获取不到网段长度就默认取17 print( '[iputils WARNING] fail to get subnet mask len. use 17 as default.' ) return 17 def cleanup_adb_forward(): for adb in ADB._instances: adb._cleanup_forwards() reg_cleanup(cleanup_adb_forward)
def __init__(self, adb): super(Javacap, self).__init__(adb) self.frame_gen = None reg_cleanup(self.teardown_stream)
def setup_stream_server(self): if self.port_forwarding: self.port, _ = self.instruct_helper.setup_proxy(9100) self.init_sock() reg_cleanup(self.teardown_stream)
def __init__(self): self.subprocessHandle = [] reg_cleanup(self.teardown)