Allow displaying only the logcat of our app. (#1272)

Todo
[ ] test with a service
[ ] consider making default
[ ] test for robustness

To discuss
[ ] should it exit automatically like it does currently? what if user reruns manually?
[ ] consider the cost of additional complexity vs usage simplification for users
This commit is contained in:
Gabriel Pettier 2021-02-21 16:40:00 +01:00 committed by GitHub
parent 7ebc048c97
commit b24b77b36e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 15 deletions

View file

@ -19,7 +19,7 @@ from buildozer.jsonstore import JsonStore
from sys import stdout, stderr, exit
from re import search
from os.path import join, exists, dirname, realpath, splitext, expanduser
from subprocess import Popen, PIPE
from subprocess import Popen, PIPE, TimeoutExpired
from os import environ, unlink, walk, sep, listdir, makedirs
from copy import copy
from shutil import copyfile, rmtree, copytree, move
@ -269,15 +269,18 @@ class Buildozer:
get_stderr = kwargs.pop('get_stderr', False)
break_on_error = kwargs.pop('break_on_error', True)
sensible = kwargs.pop('sensible', False)
run_condition = kwargs.pop('run_condition', None)
quiet = kwargs.pop('quiet', False)
if not sensible:
self.debug('Run {0!r}'.format(command))
else:
if type(command) in (list, tuple):
self.debug('Run {0!r} ...'.format(command[0]))
if not quiet:
if not sensible:
self.debug('Run {0!r}'.format(command))
else:
self.debug('Run {0!r} ...'.format(command.split()[0]))
self.debug('Cwd {}'.format(kwargs.get('cwd')))
if isinstance(command, (list, tuple)):
self.debug('Run {0!r} ...'.format(command[0]))
else:
self.debug('Run {0!r} ...'.format(command.split()[0]))
self.debug('Cwd {}'.format(kwargs.get('cwd')))
# open the process
if sys.platform == 'win32':
@ -297,9 +300,9 @@ class Buildozer:
ret_stdout = [] if get_stdout else None
ret_stderr = [] if get_stderr else None
while True:
while not run_condition or run_condition():
try:
readx = select.select([fd_stdout, fd_stderr], [], [])[0]
readx = select.select([fd_stdout, fd_stderr], [], [], 1)[0]
except select.error:
break
if fd_stdout in readx:
@ -322,7 +325,13 @@ class Buildozer:
stdout.flush()
stderr.flush()
process.communicate()
try:
process.communicate(
timeout=(1 if run_condition and not run_condition() else None)
)
except TimeoutExpired:
pass
if process.returncode != 0 and break_on_error:
self.error('Command failed: {0}'.format(command))
self.log_env(self.ERROR, kwargs['env'])
@ -337,10 +346,12 @@ class Buildozer:
self.error('raising an issue with buildozer itself.')
self.error('In case of a bug report, please add a full log with log_level = 2')
raise BuildozerCommandException()
if ret_stdout:
ret_stdout = b''.join(ret_stdout)
if ret_stderr:
ret_stderr = b''.join(ret_stderr)
return (ret_stdout.decode('utf-8', 'ignore') if ret_stdout else None,
ret_stderr.decode('utf-8') if ret_stderr else None,
process.returncode)

View file

@ -219,6 +219,9 @@ fullscreen = 0
# (str) Android logcat filters to use
#android.logcat_filters = *:S python:D
# (bool) Android logcat only display log for activity's pid
#android.logcat_pid_only = False
# (str) Android additional adb arguments
#android.adb_args = -H host.docker.internal

View file

@ -33,6 +33,7 @@ from os.path import exists, join, realpath, expanduser, basename, relpath
from platform import architecture
from shutil import copyfile, rmtree
from glob import glob
from time import sleep
from buildozer.libs.version import parse
from distutils.version import LooseVersion
@ -955,6 +956,12 @@ class TargetAndroid(Target):
cwd=self.buildozer.global_platform_dir)
self.buildozer.environ.pop('ANDROID_SERIAL', None)
while True:
if self._get_pid():
break
sleep(.1)
self.buildozer.info('Waiting for application to start.')
self.buildozer.info('Application started.')
def cmd_p4a(self, *args):
@ -1383,6 +1390,18 @@ class TargetAndroid(Target):
self.buildozer.info('Application pushed.')
def _get_pid(self):
pid, *_ = self.buildozer.cmd(
f'{self.adb_cmd} shell pidof {self._get_package()}',
get_stdout=True,
show_output=False,
break_on_error=False,
quiet=True,
)
if pid:
return pid.strip()
return False
def cmd_logcat(self, *args):
'''Show the log from the device
'''
@ -1394,10 +1413,23 @@ class TargetAndroid(Target):
"app", "android.logcat_filters", "", section_sep=":", split_char=" ")
filters = " ".join(filters)
self.buildozer.environ['ANDROID_SERIAL'] = serial[0]
self.buildozer.cmd('{adb} logcat {filters}'.format(adb=self.adb_cmd,
filters=filters),
cwd=self.buildozer.global_platform_dir,
show_output=True)
extra_args = []
pid = None
if self.buildozer.config.getdefault('app', 'android.logcat_pid_only'):
pid = self._get_pid()
if pid:
extra_args.extend(('--pid', pid))
self.buildozer.cmd(
f"{self.adb_cmd} logcat {filters} {' '.join(extra_args)}",
cwd=self.buildozer.global_platform_dir,
show_output=True,
run_condition=self._get_pid if pid else None,
break_on_error=False,
)
self.buildozer.info(f"{self._get_package()} terminated")
self.buildozer.environ.pop('ANDROID_SERIAL', None)