threes-ai icon indicating copy to clipboard operation
threes-ai copied to clipboard

ADB shell object not initializing?

Open ggallo opened this issue 6 years ago • 9 comments

I'm using a Pixel 2 XL running Android 9, with ADB version 1.0.40 on macOS. The phone is in developer mode with USB debugging enabled and is seen by ADB:

$ adb devices
List of devices attached
XXXXXXXXXX124	device

I haven't set the OCR yet, because I don't know the specific name of the device yet (though I could guess). But it doesn't matter, because every time I try android_assistant.py I get this without the phone name:

$ python android_assistant.py 
Warning: timed out waiting for prompt!
Warning: unparsed prompt u''
Traceback (most recent call last):
  File "android_assistant.py", line 144, in <module>
    exit(main(sys.argv[1:]))
  File "android_assistant.py", line 118, in main
    shell = ADBShell()
  File "/Users/x/Documents/threes-ai/android/adb_shell.py", line 394, in __init__
    self.execute('COLUMNS=10000000')
  File "/Users/x/Documents/threes-ai/android/adb_shell.py", line 442, in execute
    collected = self._send_command(cmd)
  File "/Users/x/Documents/threes-ai/android/adb_shell.py", line 424, in _send_command
    raise IOError("timed out waiting for shell echo")
IOError: timed out waiting for shell echo

I get the same error (though a slightly different trace) when trying to record events:

$ python -m android.inputemu --record up down left right
Warning: timed out waiting for prompt!
Warning: unparsed prompt u''
Traceback (most recent call last):
  File "/Users/x/.pyenv/versions/2.7.14/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/Users/x/.pyenv/versions/2.7.14/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/Users/x/Documents/threes-ai/android/inputemu.py", line 188, in <module>
    exit(main(sys.argv[1:]))
  File "/Users/x/Documents/threes-ai/android/inputemu.py", line 175, in main
    shell = ADBShell()
  File "android/adb_shell.py", line 394, in __init__
    self.execute('COLUMNS=10000000')
  File "android/adb_shell.py", line 442, in execute
    collected = self._send_command(cmd)
  File "android/adb_shell.py", line 424, in _send_command
    raise IOError("timed out waiting for shell echo")
IOError: timed out waiting for shell echo

A separate issue, but once I get that device name I'm not sure what the w, h and dx, dy OCR values are referring to. The annotated screenshot is my best guess. (Once I get it working I can do a pull request.)

ggallo avatar Aug 16 '18 02:08 ggallo

Can you run

script adb shell exit exit

and attach the contents of the “typescript” file? The “script” command is used to capture the exact output of a terminal program including any invisible characters that might be confusing the adb shell driver. On Wed, Aug 15, 2018 at 7:46 PM George Gallo [email protected] wrote:

I'm using a Pixel 2 XL running Android 9, with ADB version 1.0.40 on macOS. The phone is in developer mode with USB debugging enabled and is seen by ADB:

$ adb devices List of devices attached XXXXXXXXXX124 device

I haven't set the OCR yet, because I don't know the specific name of the device yet (though I could guess). But it doesn't matter, because every time I try android_assistant.py I get this without the phone name:

$ python android_assistant.py Warning: timed out waiting for prompt! Warning: unparsed prompt u'' Traceback (most recent call last): File "android_assistant.py", line 144, in exit(main(sys.argv[1:])) File "android_assistant.py", line 118, in main shell = ADBShell() File "/Users/x/Documents/threes-ai/android/adb_shell.py", line 394, in init self.execute('COLUMNS=10000000') File "/Users/x/Documents/threes-ai/android/adb_shell.py", line 442, in execute collected = self._send_command(cmd) File "/Users/x/Documents/threes-ai/android/adb_shell.py", line 424, in _send_command raise IOError("timed out waiting for shell echo") IOError: timed out waiting for shell echo

I get the same error (though a slightly different trace) when trying to record events:

$ python -m android.inputemu --record up down left right Warning: timed out waiting for prompt! Warning: unparsed prompt u'' Traceback (most recent call last): File "/Users/x/.pyenv/versions/2.7.14/lib/python2.7/runpy.py", line 174, in _run_module_as_main "main", fname, loader, pkg_name) File "/Users/x/.pyenv/versions/2.7.14/lib/python2.7/runpy.py", line 72, in _run_code exec code in run_globals File "/Users/x/Documents/threes-ai/android/inputemu.py", line 188, in exit(main(sys.argv[1:])) File "/Users/x/Documents/threes-ai/android/inputemu.py", line 175, in main shell = ADBShell() File "android/adb_shell.py", line 394, in init self.execute('COLUMNS=10000000') File "android/adb_shell.py", line 442, in execute collected = self._send_command(cmd) File "android/adb_shell.py", line 424, in _send_command raise IOError("timed out waiting for shell echo") IOError: timed out waiting for shell echo

A separate issue, but once I get that device name I'm not sure what the w, h and dx, dy OCR values are referring to. The annotated screenshot is my best guess. (Once I get it working I can do a pull request.)

https://user-images.githubusercontent.com/3633936/44184061-b03efc80-a0db-11e8-8a07-bfbaff2ac13b.png

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/nneonneo/threes-ai/issues/15, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEmuc8i1MqGfVWRdf-pUHAYkZFxFwSbks5uRNz8gaJpZM4V_HHb .

nneonneo avatar Aug 16 '18 03:08 nneonneo

Look at that...

Script started on Wed Aug 15 23:49:51 2018
ESC[?1034hggallo@Mac:~$ adb shell
taimen:/ $ exit
ggallo@Mac:~$ exit
exit

Script done on Wed Aug 15 23:49:57 2018

ggallo avatar Aug 16 '18 03:08 ggallo

I'll probably need the actual contents of the typescript file that it generates, rather than your Terminal output, since it's the invisible characters that I'm after.

Also, FYI, dx/dy represent the grid spacing, which is the width/height of a tile plus the spacing between tiles. For best results, tw should be wide enough to capture all three upcoming tiles in the event of an impending "high" spawn.

nneonneo avatar Aug 16 '18 05:08 nneonneo

Understood. Here's the actual file: typescript.txt

ggallo avatar Aug 16 '18 13:08 ggallo

I pushed a speculative fix in 8271820, please try it out.

nneonneo avatar Aug 16 '18 14:08 nneonneo

Sorry for delay here.

Tried with no luck. Upped the init to 600 seconds just to be sure but got same traces. Worth noting: I can get the prompt when I don't use the PIPEs:

ggallo@Mac:threes-ai (master *=)$ python
Python 2.7.14 (default, Aug 15 2018, 22:23:05) 
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from subprocess import Popen, PIPE
>>> p = Popen(['adb', 'shell'])
>>> taimen:/ $ ^D

I'll keep working on this. I think I'm close to a fix.

ggallo avatar Aug 18 '18 20:08 ggallo

Ok. My best guess is that the new adb shell is doing some kind of TTY check, which would unfortunately necessitate using a library like pexpect. This dependency makes the program somewhat harder to deploy. Unfortunately I don’t have a new enough phone to test this out. On Sat, Aug 18, 2018 at 4:47 PM George Gallo [email protected] wrote:

Sorry for delay here.

Tried with no luck. Upped the init to 600 seconds just to be sure but got same traces. Worth noting: I can get the prompt when I don't use the PIPEs:

ggallo@Mac:threes-ai (master *=)$ python Python 2.7.14 (default, Aug 15 2018, 22:23:05) [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information.

from subprocess import Popen, PIPE p = Popen(['adb', 'shell']) taimen:/ $ ^D

I'll keep working on this. I think I'm close to a fix.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/nneonneo/threes-ai/issues/15#issuecomment-414085444, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEmuZUPfoPq3St9r-I_pqks6g_OdMDNks5uSH1YgaJpZM4V_HHb .

nneonneo avatar Aug 20 '18 18:08 nneonneo

I realize this is a 2-year-old issue (and this code hasn't been updated in a while); I have very little experience doing something like this, but I did work out that adding:

    cmd += ['-tt']

at line 336 of adb_shell.py prevents the timeout, but at that point, the command just spins. Inserting various debug output in the code shows me that the code is running properly, but not being super familiar with using OOP in python (I typically write simple scripts that don't instantiate objects), I'm not sure how to proceed with debugging.

The -tt switch forces adb to allocate a pty (using -t results in the message 'Remote PTY will not be allocated because stdin is not a terminal.` - so this seems to be the core of the issue.)

Perhaps this will help someone create a workaround/fix for the issue.

ETA: It does look like the method of grepping /system/build.prop won't work now either, using getprop will be needed. It also looks like using the -tt switch may prevent input from being passed to the device.

hendersj avatar Aug 13 '20 01:08 hendersj

Thanks for looking into it. I no longer own a working Android device so I can’t debug the issue, but you might be able to figure out where it’s hanging by getting a trace back with Ctrl+C or the like.

As hinted in my previous comment, the right solution is probably a library like pexpect, which implements a proper pseudo-TTY and can therefore interface correctly with ADB in TTY mode. Without it, there’s likely to be a lot of brokenness since ADB will expect to talk to a TTY (not just a plain pipe).

pexpect is relatively easy to set up and use, but I’m hesitant to implement it because i wouldn’t be able to test it. My biggest concern would be whether it is still possible to receive binary data (images/screenshots) through pexpect/TTY or whether the terminal protocol would mangle it (e.g. CRLF translation). Another approach would be to simply replace adb_shell.py with a library that wraps ADB shell, if such a library exists.

nneonneo avatar Aug 13 '20 07:08 nneonneo