Starts the underlying 'adb shell' process.
(self)
| 45 | self._consume_initial_prompt() |
| 46 | |
| 47 | def _start_shell(self) -> subprocess.Popen: |
| 48 | """Starts the underlying 'adb shell' process.""" |
| 49 | cmd = [self.adb_path] |
| 50 | if self.device_id: |
| 51 | cmd.extend(["-s", self.device_id]) |
| 52 | cmd.append("shell") |
| 53 | |
| 54 | try: |
| 55 | # Start the shell process. Stderr is redirected to stdout to |
| 56 | # capture all output in one stream. We use a specific encoding |
| 57 | # and a line-buffered mode. |
| 58 | return subprocess.Popen( |
| 59 | cmd, |
| 60 | stdin=subprocess.PIPE, |
| 61 | stdout=subprocess.PIPE, |
| 62 | stderr=subprocess.STDOUT, |
| 63 | text=True, |
| 64 | encoding="utf-8", |
| 65 | errors="replace", |
| 66 | bufsize=1, |
| 67 | ) |
| 68 | except FileNotFoundError: |
| 69 | raise RuntimeError(f"ADB executable not found at '{self.adb_path}'") |
| 70 | except Exception as e: |
| 71 | raise RuntimeError(f"Failed to start adb shell: {e}") |
| 72 | |
| 73 | def _consume_initial_prompt(self): |
| 74 | """Executes a simple command to clear any initial login messages.""" |