2

I'm doing a python 2.7 plugin that perform some tests on android devices.

One of my test use an adb command, but this command is doing an infinite loop on some devices.

command: adb shell am start -W -a android.intent.action.VOICE_COMMAND

expected output:

Starting: Intent { act=android.intent.action.VOICE_COMMAND }
Status: ok
Activity: com.google.android.googlequicksearchbox/com.google.android.apps.gsa.velour.dynamichosts.TransparentVelvetDynamicHostActivity
ThisTime: 241
TotalTime: 659
WaitTime: 684
Complete

On most of my devices this command work well but on other it loop and never return something.

I tryed to call this command into a thread, but even doing this I can't figure out how to kill that thread after a timeout.

Here is what I have already tryed (see this) but none of these work because the thread is locked into that infinite loop call and so I can't check if an "end" variable is set into this thread, nor handle event.

Is there a way to kill this Thread after a certain amount of time with something like this ? =>

endtime = time.time() + 20
t1 = MyThread(my_func, "my_args", "my_args2")
while True:
    if time.time() > endtime:
        end_thread(t1) # or t1.end() or idk
    else:
        time.sleep(1)
4
  • This post suggests wrap threads in subprocess so they can be safely terminated. Commented May 9, 2019 at 8:44
  • Using multiprocessing is not a solution for my plugin, it have some unexcepted behavior on devices. This python module contain like 50 sub-plugins who perform test on android devices. Using multiprocessing on my plugin used to make false some test on others plugins. Commented May 9, 2019 at 8:52
  • You haven't shown us how you're starting adb. If you're using the subprocess module, there is a timeout option in Python 3 (and the same feature is available in the subprocess32 backport to Python 2). Commented May 9, 2019 at 11:17
  • I'm starting adb by using adb.shell(args). This is a module in my program designed for various use of adb. adb.shell use another module, command.py and in this module the adb command is executed into a subprocess using subprocess.Popen(). I didn't knew until now that the adb.shell method actually use subprocess. I'll try to add some kind of timeout to this. Commented May 9, 2019 at 12:24

1 Answer 1

1

Resolved my issue.

I used subprocess like this:

Module command.py

import subprocess
# [...]
def execute(cmd, args=None, display_cmd=False, disable_out=False, disable_error=False, no_wait=False, is_shell=False):
    if cmd is None:
        return None

    cmd_args = [cmd]

    if args is not None:
        for arg in args:
            cmd_args.append(str(arg))

    if display_cmd:
        str_cmd = None
        for arg in cmd_args:
            if str_cmd is None:
                str_cmd = str(arg)
            else:
                str_cmd = str_cmd + " " + str(arg)
        Logs.instance().debug(str_cmd)

    std_out = subprocess.PIPE
    if disable_out:
        std_out = DEVNULL

    if no_wait:
        subprocess.Popen(cmd_args, stdin=None, stdout=None, stderr=None, shell=is_shell)
        return None
    elif disable_error:
        p = subprocess.Popen(cmd_args, stdout=std_out, stderr=DEVNULL, shell=is_shell)
    else:
        p = subprocess.Popen(cmd_args, stdout=std_out, shell=is_shell)

    if disable_out:
        return None
    else:
        out = p.stdout.read()
        return out

Module adb.py

def shell(cmd, no_wait=False):
    data = cmd.split()
    if data[0] != "shell":
        data.insert(0, "shell")
    if no_wait:
        result = command.execute("adb", data, no_wait=True)
    else:
        result = command.execute("adb", data)
    return result

My plugin

def _my_test(self, x, y):
    result = adb.shell("shell am start -W -a android.intent.action.VOICE_COMMAND", no_wait=True)
    if not result:
        # handle
    else:
        # [...]

Thank you, hope it will help someone one day

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.