Skip to content

Commit 20e5bcd

Browse files
douglas-raillard-armmarcbonnici
authored andcommitted
utils/android: Restore adb root state when disconnecting
The current behavior is to issue "adb unroot" if the device needed to be rooted upon connection. This breaks use of nested Targets, which LISA requires as some target interaction needs to happen in a subprocess. Fix that by restoring the same adb root state that there was when creating the connection, rather than blindly unrooting the device upon disconnection.
1 parent f60fa59 commit 20e5bcd

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

devlib/utils/android.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,14 @@ def __init__(
305305
self.adb_server = adb_server
306306
self.adb_port = adb_port
307307
self.adb_as_root = adb_as_root
308+
self._restore_to_adb_root = False
308309
lock, nr_active = AdbConnection.active_connections
309310
with lock:
310311
nr_active[self.device] += 1
311312

312313
if self.adb_as_root:
313314
try:
314-
self.adb_root(enable=True)
315+
self._restore_to_adb_root = self._adb_root(enable=True)
315316
# Exception will be raised if we are not the only connection
316317
# active. adb_root() requires restarting the server, which is not
317318
# acceptable if other connections are active and can apparently
@@ -405,7 +406,7 @@ def _close(self):
405406

406407
if disconnect:
407408
if self.adb_as_root:
408-
self.adb_root(enable=False)
409+
self.adb_root(enable=self._restore_to_adb_root)
409410
adb_disconnect(self.device, self.adb_server, self.adb_port)
410411

411412
def cancel_running_command(self):
@@ -415,27 +416,34 @@ def cancel_running_command(self):
415416
pass
416417

417418
def adb_root(self, enable=True):
419+
self._adb_root(enable=enable)
420+
421+
def _adb_root(self, enable):
418422
lock, nr_active = AdbConnection.active_connections
419423
with lock:
420424
can_root = nr_active[self.device] <= 1
421425

422426
if not can_root:
423427
raise AdbRootError('Can only restart adb server if no other connection is active')
424428

429+
def is_rooted(out):
430+
return 'adbd is already running as root' in out
431+
425432
cmd = 'root' if enable else 'unroot'
426433
try:
427434
output = adb_command(self.device, cmd, timeout=30, adb_server=self.adb_server, adb_port=self.adb_port)
428435
except subprocess.CalledProcessError as e:
436+
was_rooted = is_rooted(e.output)
429437
# Ignore if we're already root
430-
if 'adbd is already running as root' in e.output:
431-
pass
432-
else:
438+
if not was_rooted:
433439
raise AdbRootError(str(e)) from e
434440
else:
441+
was_rooted = is_rooted(output)
435442
# Check separately as this does not cause a error exit code.
436443
if 'cannot run as root in production builds' in output:
437444
raise AdbRootError(output)
438445
AdbConnection._connected_as_root[self.device] = enable
446+
return was_rooted
439447

440448
def wait_for_device(self, timeout=30):
441449
adb_command(self.device, 'wait-for-device', timeout, self.adb_server, self.adb_port)

0 commit comments

Comments
 (0)