Esempio n. 1
0
 def check_okay(self):
     data = self.read(4)
     if data == _FAIL:
         raise AdbError(self.read_string())
     elif data == _OKAY:
         return
     raise AdbError("Unknown data: %s" % data)
Esempio n. 2
0
 def iter_content(self, path: str):
     with self._prepare_sync(path, "RECV") as c:
         while True:
             cmd = c.read(4)
             if cmd == _FAIL:
                 str_size = struct.unpack("<I", c.read_raw(4))[0]
                 error_message = c.read(str_size)
                 raise AdbError(error_message)
             elif cmd == _DONE:
                 break
             elif cmd == _DATA:
                 chunk_size = struct.unpack("<I", c.read_raw(4))[0]
                 chunk = c.read_raw(chunk_size)
                 if len(chunk) != chunk_size:
                     raise RuntimeError("read chunk missing")
                 yield chunk
             else:
                 raise AdbError("Invalid sync cmd", cmd)
Esempio n. 3
0
 def read_string(self) -> str:
     """
     Raises:
         AdbError
     """
     length = self.read(4)
     if not length:
         raise AdbError("connection closed")
     size = int(length, 16)
     return self.read(size)
Esempio n. 4
0
    def _raw_window_size(self) -> WindowSize:
        output = self.shell("wm size")
        m = re.search(r"Physical size: (\d+)x(\d+)", output)
        if m:
            w, h = m.group(1), m.group(2)
            return WindowSize(int(w), int(h))

        for line in self.shell('dumpsys display').splitlines():
            m = _DISPLAY_RE.search(line, 0)
            if not m:
                continue
            w = int(m.group('width'))
            h = int(m.group('height'))
            return WindowSize(w, h)
        raise AdbError("get window size failed")
Esempio n. 5
0
    def rotation(self) -> int:
        """
        Returns:
            int [0, 1, 2, 3]
        """
        for line in self.shell('dumpsys display').splitlines():
            m = _DISPLAY_RE.search(line, 0)
            if not m:
                continue
            o = int(m.group('orientation'))
            return int(o)

        output = self.shell(
            'LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -i')
        try:
            data = json.loads(output)
            return data['rotation'] / 90
        except ValueError:
            pass

        raise AdbError("rotation get failed")
Esempio n. 6
0
    def current_app(self):
        """
        Returns:
            dict(package, activity, pid?)

        Raises:
            AdbError
        """
        # Related issue: https://github.com/openatx/uiautomator2/issues/200
        # $ adb shell dumpsys window windows
        # Example output:
        #   mCurrentFocus=Window{41b37570 u0 com.incall.apps.launcher/com.incall.apps.launcher.Launcher}
        #   mFocusedApp=AppWindowToken{422df168 token=Token{422def98 ActivityRecord{422dee38 u0 com.example/.UI.play.PlayActivity t14}}}
        # Regexp
        #   r'mFocusedApp=.*ActivityRecord{\w+ \w+ (?P<package>.*)/(?P<activity>.*) .*'
        #   r'mCurrentFocus=Window{\w+ \w+ (?P<package>.*)/(?P<activity>.*)\}')
        _focusedRE = re.compile(
            r'mCurrentFocus=Window{.*\s+(?P<package>[^\s]+)/(?P<activity>[^\s]+)\}'
        )
        m = _focusedRE.search(self._run(['dumpsys', 'window', 'windows']))
        if m:
            return dict(
                package=m.group('package'), activity=m.group('activity'))

        # try: adb shell dumpsys activity top
        _activityRE = re.compile(
            r'ACTIVITY (?P<package>[^\s]+)/(?P<activity>[^/\s]+) \w+ pid=(?P<pid>\d+)'
        )
        output = self._run(['dumpsys', 'activity', 'top'])
        ms = _activityRE.finditer(output)
        ret = None
        for m in ms:
            ret = dict(
                package=m.group('package'),
                activity=m.group('activity'),
                pid=int(m.group('pid')))
        if ret:  # get last result
            return ret
        raise AdbError("Couldn't get focused app")
Esempio n. 7
0
 def push(self,
          src: typing.Union[pathlib.Path, str, bytes, bytearray, typing.BinaryIO],
          dst: str,
          mode: int = 0o755,
          check: bool = False) -> int:
     # IFREG: File Regular
     # IFDIR: File Directory
     if isinstance(src, pathlib.Path):
         src = src.open("rb")
     elif isinstance(src, str):
         src = pathlib.Path(src).open("rb")
     elif isinstance(src, (bytes, bytearray)):
         src = io.BytesIO(src)
     else:
         if not hasattr(src, "read"):
             raise TypeError("Invalid src type: %s" % type(src))
     path = dst + "," + str(stat.S_IFREG | mode)
     total_size = 0
     with self._prepare_sync(path, "SEND") as c:
         r = src if hasattr(src, "read") else open(src, "rb")
         try:
             while True:
                 chunk = r.read(4096)
                 if not chunk:
                     mtime = int(datetime.datetime.now().timestamp())
                     c.conn.send(b"DONE" + struct.pack("<I", mtime))
                     break
                 c.conn.send(b"DATA" + struct.pack("<I", len(chunk)))
                 c.conn.send(chunk)
                 total_size += len(chunk)
             assert c.read_string(4) == _OKAY
         finally:
             if hasattr(r, "close"):
                 r.close()
     if check:
         file_size = self.stat(dst).size
         if total_size != file_size:
             raise AdbError("Push not complete, expect pushed %d, actually pushed %d" % (total_size, file_size))
     return total_size