Relax the shell command length limits when talking to an adbd with the
shell protocol.
shell is pretty much the only service that takes an arbitrarily long
string, so this is somewhat safe.
Bug: http://b/37716055
Test: `adb shell $(python -c 'print "echo " + "f" * (32*1024)') | wc` on L and master
Change-Id: I0737fd2244530ef8080f300cd3a3549a1ab93465
Previously, adb was assuming a fixed maximum packet size of 1024 bytes
(the value for an endpoint connected via USB 3.0). When connected to an
endpoint that has an actual maximum packet size of 512 bytes (i.e.
every single device over USB 2.0), the following could occur:
device sends amessage with 512 byte payload
client reads amessage
client tries to read payload with a length of 1024
In this scenario, the kernel will block, waiting for an additional
packet which won't arrive until something else gets sent across the
wire, which will result in the previous read failing, and the new
packet being dropped.
Bug: http://b/37783561
Test: python test_device.py on linux/darwin, with native/libusb
Change-Id: I556f5344945e22dd1533b076f662a97eea24628e
When device goes offline, user usually has to manually replug the
usb device. This patch tries to solve two offline situations, all
because when adb on host is killed, the adbd on device is not notified.
1. When adb server is killed while pushing a large file to device,
the device is still reading the unfinished large message. So the
device thinks of the CNXN message as part of the previous unfinished
message, so it doesn't reply and the device is in offline state.
The solution is to add a write_msg_lock in atransport struct. And it
kicks the transport only after sending a whole message. By kicking
all transports before exit, we ensure that we don't write part of
a message to any device. So next time we start adb server, the device
should be waiting for a new message.
2. When adb server is killed while pulling a large file from device,
the device is still trying to send the unfinished large message. So
adb on host usually reads data with EOVERFLOW error. This is because
adb on host is reading less than one packet sent from device.
The solution is to use buffered read on host. The max packet size
of bulk transactions in USB 3.0 is 1024 bytes. By preparing an at least
1024 bytes buffer when reading, EOVERFLOW no longer occurs. And teach
adb host to ignore wrong messages.
To be safe, this patch doesn't change any logic on device.
Bug: http://b/32952319
Test: run python -m unittest -q test_device.DeviceOfflineTest
Test: on linux/mac/windows with bullhead, ryu.
Change-Id: Ib149d30028a62a6f03857b8a95ab5a1d6e9b9c4e
Be agnostic to whether /system is writable when testing push error
reporting.
Test: python test_device.py
Change-Id: I1d03564fa35442c20e2c96a7f5b56d39868efc52
Fix race condition in the test_non_interactive_sigint test by
looping for a while.
Bug: http://b/32336914
Test: python test_device.py
Change-Id: Ie65a762ad6f04815231add5444762c4c0ffd31cb
From the bug:
Say we run a new adb against an old device (like KitKat). Even with a new
client ADB, in this configuration, "adb shell" will create a remove tty
unconditionally. So if the user runs "adb shell -t -t", we shouldn't fail
with a message about the remote device not supporting -tT options --- the
user asked to create a tty unconditionally, and since we're going to create
a tty unconditionally, we should just succeed. (That it's going to succeed
due to protocol inadequacy instead of succeeding on purpose is irrelevant.)
That adb fails in this case makes scripts more complicated, since they can't
just pass "-t -t" unconditionally if they want a tty and to work on all
device versions, even if the script requires a new-ish adb locally.
Bug: http://b/32216152
Bug: http://b/32219151
Test: test_device.py
Change-Id: I8ab7c8dfa212209a7ab43c1f0832eeac26d2e42f
This keeps regressing, so add a test to keep this from happening.
Bug: http://b/23603716
Bug: http://b/25965770
Bug: http://b/29565233
Test: Ran test with/without commit cd5d737, fails before, passes after
Change-Id: I8c431e10fc76da5a9fd404dd70f17bb8a8df24e6
This CL adds support to forward or reverse TCP port 0 to allow the
system to automatically select an open port. The resolved port number
will be printed to stdout:
$ adb forward tcp:0 tcp:8000
12345
$ adb reverse tcp:0 tcp:9000
23456
This allows testing to be more robust by not hardcoding TCP ports which
may already be in use.
Forwarding port 0 is a host-only change and will work with any device,
but reversing port 0 requires the device to be updated with a new adbd
binary.
This CL also does a little bit of cleanup such as moving the alistener
class out of adb.h, and adds some error checking and additional tests.
Bug: 28051746
Test: python -m unittest discover
Test: adb_test
Test: `adb forward` and `adb reverse` with tcp:0
Change-Id: Icaa87346685b403ab5da7f0e6aa186aa091da572
https://android-review.googlesource.com/#/c/210646/ added a
has_shell_protocol() function but the test_device.py tests were still
trying to use the now-missing SHELL_PROTOCOL_FEATURE constant.
This CL just switches test_device.py to correctly use the
has_shell_protocol() method.
Change-Id: Ie0a2f0dc07529843d25051a01e08fb677551a4e1
Test: `python -m unittest discover -v` on devices with and without
the shell protocol.
This matches scp's behavior when pulling a directory that collides
with a symlink to a directory.
Bug: http://b/27362811
Change-Id: I0936d1ad48f13e24cd382e8e8400cc752bac3b66
When sending a file, do a 0-timeout poll to check to see if an error has
occurred, so that we can immediately report failure.
Bug: http://b/26816782
Change-Id: I4a8aa8408a36940bfda7b0ecfa5d13755f4aa14d
We want to be able to use this in the NDK without having to pull in
all of system core.
Also, this clarifies the separation of adb and its python interface.
Bug: http://b/22881740
Change-Id: I0b437d9bf621e371d4698d7f8e8828072c7ff347
When the client exits (e.g. with Ctrl+C) the subprocess should be
notified as well so it can cleanup if needed.
Bug: http://b/23825725
Change-Id: Idb771710b293e0a9f7bebc9e2814b3a816e2c50e
It wasn't deleting the tempfile.mkdtemp() dir that it made.
Change-Id: I59c5f98aa8297c7b28d38799dd21ffe9566f2145
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
Adds the shell protocol functionality to the client side and enables it
if the transport supports the feature.
Bug:http://b/23031026
Change-Id: I9abe1c8b1d39f8dd09666321b1c761ad708a8854
adb push was not returning a bad exit code when write_data_file() or
write_data_link() failed. I encountered this when running the unittest
on Windows which can get into situations where stat() succeeds, but
open() fails due to pre-existing exclusive file access (which typically
doesn't exist on unix).
The same code is used by adb install, so this also fixes its error
handling.
Fixed some fd leaks and propagation of errors when reading a file.
Fixed a unittest to close temp files before reading them.
Change-Id: Ieba0026fa4c79eb0484676e4f2faaac9603ef584
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
The Python 2 subprocess class doesn't use Unicode, so as a work-around
write the command line to a UTF-8 batch file and run that.
I modified the test to use u'blah' without .encode('utf-8') because the
Python docs recommend dealing with string variables like that. When
formatting a string with a unicode parameter, use u'foo' on the constant
string to make it unicode.
I also tested this on Linux and it seems to work fine (I did ls in the
middle of the test to make sure the filenames came out right, etc.).
I had to close the temporary files before adb tries to read/write them
because filesystem semantics are different on Windows (technically I
might be able to modify adb to try to open files with more permissive
share flags, but then I'm not sure if Python uses the right share flags.
Basically, I'd be opening another can of worms.).
Fixed the test to delete a temp file on the device once it is done.
Change-Id: Id0c34e26d7697fbbb47a44ae45298bed5e8c59d6
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
Change `adb shell` so that interactive sessions use a PTY but
non-interactive do not. This matches `ssh` functionality better
and also enables future work to split stdout/stderr for
non-interactive sessions.
A test to verify this behavior is added to test_device.py with
supporting modifications in device.py.
Bug: http://b/21215503
Change-Id: Ib4ba40df85f82ddef4e0dd557952271c859d1c7b
Not seeing the full output from the failed adb command is probably
the biggest issue when debugging a test failure, but this doesn't
help either.
Change-Id: Ic42cbced8be252185a799b27c210a744188a4201
If ANDROID_SERIAL was not set, test_device.py was failing.
Use posixpath.join instead of os.path.join for make_random_device_files.
Change-Id: I24bfa43ba2a89a9a768f505fc0bba9d873082b2f
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
Had messed this up while refactoring before I submitted and neglected
to add a test. Thanks to mazda@ for catching this.
Also disabled the root/unroot tests for user builds.
Change-Id: Icb819a820a2afa227d548d678ae471d5195f0b96
This is mostly just the AdbWrapper that we used in our tests, but I've
cleaned up the API to be a little more Pythonic (mostly in the sense
that commands are passed as lists rather than strings that are
shlex.split() by the shell command), and implemented the workaround
error checking for adb shell.
Move the tests up a directory. Having them buried a level down has
only been annoying.
There are now two files containing Python tests. test_device.py
contains tests specifically checking the AndroidDevice API, and
test_adb.py checks the ADB client program. To run both, use
python -m unittest discover [-v]
Change-Id: Ibd158c528d31126a5b048bd00bc93039dbc468bc