If several devices are connected (as listed by `adb devices`), it was
necessary to provide the explicit serial via -s/--serial.
If only one device is connected via USB (respectively, via TCP/IP), it
might be convenient to select it automatically. For this purpose, two
new options are introduced:
- -d/--select-usb: select the single device connected over USB
- -e/--select-tcpip: select the single device connected over TCP/IP
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
Currently, a device is selected either from a specific serial, or if it
is the only one connected.
In order to support selecting the only device connected via USB or via
TCP/IP separately, introduce a new selection structure.
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
This does nothing if the adb daemon is already started, but allows to
print any output/errors to the console.
Otherwise, the daemon starting would occur during `adb devices`, which
does not output to the console because the result is parsed.
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
Since the previous commit, if a serial is given via -s/--serial (either
a real USB serial or an IP:port), a device is selected if its serial
matches exactly.
In addition, if the user pass an IP without a port, then select any
device with this IP, regardless of the port (so that "192.168.1.1"
matches any "192.168.1.1:port"). This is also the default behavior of
adb.
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
List all USB devices in a first step, then select the matching one(s).
This allows to report a user-friendly log message containing the list of
devices, with the matching one(s) highlighted.
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
One log macro was provided for each log level (LOGV(), LOGD(), LOGI(),
LOGW(), LOGE()).
Add a generic macro LOG(LEVEL, ...) accepting a log level as parameter,
so that it is possible to write logging wrappers.
PR #3005 <https://github.com/Genymobile/scrcpy/pull/3005>
This util function was error-prone:
- it accepted a buffer as parameter (not necessarily a NUL-terminated
string) and its length (including the NUL char, if any);
- it wrote '\0' over the last character of the buffer, so the last
character was lost if the buffer was not a NUL-terminated string, and
even worse, it caused undefined behavior if the length was empty;
- it returned the length of the resulting NUL-terminated string,
which was inconsistent with the input buffer length.
In addition, it was not necessarily optimal:
- it wrote '\0' twice;
- it required to know the buffer length, that is the input string
length + 1, in advance.
Remove this function, and let the client use strcspn() manually.
The function assumed that the raw output of "adb connect" was a
NUL-terminated string, but it is not the case.
It this output did not end with a space or a new line character, then
sc_str_truncate() would write '\0' over the last character. Even worse,
if the output was empty, then sc_str_truncate() would write
out-of-bounds.
Avoid the error-prone sc_str_truncate() util function.
The function assumed that the raw output of "adb get-serialno" was a
NUL-terminated string, but it is not the case.
It this output did not end with a space or a new line character, then
sc_str_truncate() would write '\0' over the last character. Even worse,
if the output was empty, then sc_str_truncate() would write
out-of-bounds.
Avoid the error-prone sc_str_truncate() util function.
The function assumed that the raw output of "adb getprop" was a
NUL-terminated string, but it is not the case.
It this output did not end with a space or a new line character, then
sc_str_truncate() would write '\0' over the last character. Even worse,
if the output was empty, then sc_str_truncate() would write
out-of-bounds.
Avoid the error-prone sc_str_truncate() util function.
The parser assumed that its input was a NUL-terminated string, but it
was not the case: it is just the raw output of "adb devices ip route".
In practice, it was harmless, since the output always ended with '\n'
(which was replaced by '\0' on truncation), but it was incorrect
nonetheless.
Always write a '\0' at the end of the buffer, and explicitly parse as a
NUL-terminated string. For that purpose, avoid the error-prone
sc_str_truncate() util function.
Before starting the server, the actual device serial (possibly its
ip:port if it's over TCP/IP) must be known.
A serial might be requested via -s/--serial (stored in the
sc_server_params), but the actual serial may change afterwards:
- if none is provided, then it is retrieved with "adb get-serialno";
- if --tcpip is requested, then the final serial will be the target
ip:port.
The requested serial was overwritten by the actual serial in the
sc_server_params struct, which was a bit hacky.
Instead, store a separate serial field in sc_server (and rename the one
from sc_server_params to "req_serial" to avoid confusion).
Now that providing a serial is mandatory for adb commands where it is
relevant, the whole argv array may be built statically, without
allocations at runtime.
If no serial is passed, then the command would work if there is exactly
one device connected, but will fail with multiple devices.
To avoid such cases, ensure that a serial is always provided.
On Windows, adb is provided in the release archive. Most missing adb
issues come from users setting the ADB environment variable to an
incorrect value (on all platforms).
Suggesting to install platform-tools to solve the problem will just make
things worse (there will be one more adb in yet another location).
The new retry mechanism with a lower definition only worked if the error
occurred during encode(). For example:
java.lang.IllegalStateException
at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:3452)
at com.genymobile.scrcpy.ScreenEncoder.encode(ScreenEncoder.java:114)
at com.genymobile.scrcpy.ScreenEncoder.internalStreamScreen(ScreenEncoder.java:95)
at com.genymobile.scrcpy.ScreenEncoder.streamScreen(ScreenEncoder.java:61)
at com.genymobile.scrcpy.Server.scrcpy(Server.java:80)
at com.genymobile.scrcpy.Server.main(Server.java:255)
However, MediaCodec may also fail before encoding, during configure() or
start(). For example:
android.media.MediaCodec$CodecException: Error 0xfffffc0e
at android.media.MediaCodec.native_configure(Native Method)
at android.media.MediaCodec.configure(MediaCodec.java:1956)
at android.media.MediaCodec.configure(MediaCodec.java:1885)
at com.genymobile.scrcpy.ScreenEncoder.configure(ScreenEncoder.java:158)
at com.genymobile.scrcpy.ScreenEncoder.streamScreen(ScreenEncoder.java:68)
at com.genymobile.scrcpy.Server.scrcpy(Server.java:28)
at com.genymobile.scrcpy.Server.main(Server.java:110)
Also downscale and retry in these cases.
Refs #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
Refs #2988 <https://github.com/Genymobile/scrcpy/issues/2988>
PR #2990 <https://github.com/Genymobile/scrcpy/pull/2990>
The function was initially implemented to truncate lines, but was later
generalized to accept custom delimiters. The whole documentation has not
been updated accordingly.
Refs 9619ade706