Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve device selection #3005

Merged
merged 16 commits into from Feb 9, 2022
Merged

Improve device selection #3005

merged 16 commits into from Feb 9, 2022

Conversation

rom1v
Copy link
Collaborator

@rom1v rom1v commented Feb 6, 2022

Currently, if several devices are connected, scrcpy fails with:

$ scrcpy
scrcpy 1.22 <https://github.com/Genymobile/scrcpy>
error: more than one device/emulator
ERROR: "adb get-serialno" returned with value 1
ERROR: Could not get device serial
ERROR: Server connection failed

This is not very user-friendly: the user must call adb devices manually to get the serial, then call scrcpy -s xxxxxxxxxx explicitly.

This PR brings features to improve device selection.

If several devices are connected, scrcpy prints the list of devices:

$ scrcpy

ERROR: Multiple (3) ADB devices:
ERROR:     -->   (usb)  fedcba09                        device  GM1913
ERROR:     -->   (usb)  01234567890abcdef         unauthorized  
ERROR:     --> (tcpip)  192.168.1.1:5555                device  Nexus_5
ERROR: Select a device via -s (--serial), -d (--select-usb) or -e (--select-tcpip)
ERROR: Server connection failed

So it is possible to immediately call scrcpy again with -s.

In addition, two new options allow to select a USB or TCP/IP device when there is only one connected:

  • -d (or --select-usb) uses a USB device (like adb -d)
  • -e (or --select-tcpip) uses a TCP/IP device (like adb -e)

For example, to run scrcpy with the single TCP/IP device:

$ scrcpy -e

DEBUG: ADB device found:
DEBUG:           (usb)  fedcba09                        device  GM1913
DEBUG:           (usb)  05f5e60a0ae518e5          unauthorized  
DEBUG:     --> (tcpip)  192.168.1.1:5555                device  Nexus_5

To run scrcpy with a single USB device:

$ scrcpy -d

ERROR: Multiple (2) ADB devices over USB:
ERROR:     -->   (usb)  fedcba09                        device  GM1913
ERROR:     -->   (usb)  01234567890abcdef         unauthorized  
ERROR:         (tcpip)  192.168.1.1:5555                device  Nexus_5
ERROR: Select a device via -s (--serial), -d (--select-usb) or -e (--select-tcpip)
ERROR: Server connection failed

Since there are several devices connected over USB in this example, it fails, with a detailed error message.

Notice that the list of devices is printed at DEBUG level if it works (so it is not printed in release mode unless -Vdebug is passed), whereas it is printed at ERROR level if it fails.
(Maybe we should print it at INFO level when everything works, so that it is always printed?)

The first commits implement the same behavior for listing USB devices for HID/OTG mode (introduced in v1.22:

$ scrcpy --otg

ERROR: Multiple (2) USB devices:
ERROR:     --> fedcba09           (xxxx:xxxx)  OnePlus SM8150-MTP
ERROR:     --> 01234567890abcdef  (xxxx:xxxx)  LGE Nexus 5
ERROR: Select a device via -s (--serial)

Do not conflate --select-tcpip with the --tcpip option introduced in v1.21.

  • --tcpip (without argument):
    1. connects to the selected device (which could be selected via -s, even -U or -T)
    2. enables TCP/IP mode (execute adb tcpip 5555)
    3. retrieves the device IP (by parsing adb shell ip route)
    4. connects to the device (adb connect IP:5555)
    5. starts mirroring
  • --select-tcpip just selects a device already connected (i.e. listed in adb devices) via TCP/IP

In hindsight, maybe --tcpip should have been called --connect-tcpip or similar to avoid confusion, but it's too late.

@erawhctim
Copy link

maybe -U should be replaced by -d and -T replaced by -e to match what adb provides

This sounds ideal 👌 matches the muscle memory from using adb standalone

@rom1v
Copy link
Collaborator Author

rom1v commented Feb 7, 2022

This sounds ideal 👌 matches the muscle memory from using adb standalone

Thank you for your feedback.

On the other hand, these adb options were intended to select device (-d) VS emulator (-e), and their semantics have shifted to usb VS tcpip. I'm not sure using these legacy letters is a good idea (in practice, scrcpy never mirrors an emulator, and everything is a device).

@rom1v rom1v force-pushed the adb_devices branch 3 times, most recently from bf16261 to 47ec09b Compare February 8, 2022 12:39
@rom1v
Copy link
Collaborator Author

rom1v commented Feb 8, 2022

I changed to -d and -e.

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 <#3005>
Rename from "usb_device_" to "usb_devices_".

PR #3005 <#3005>
Define the printf format macro for size_t in compat.h so that it can be
used from anywhere.

PR #3005 <#3005>
Add a function to "move" a sc_usb_device into another instance.

This will avoid unnecessary copies.

PR #3005 <#3005>
The caller just wants a single device. Handle all cases and error
messages internally.

PR #3005 <#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 <#3005>
Depending on the parameters passed to scrcpy, either the initial device
serial is necessary or not. Reorganize to simplify the logic.

PR #3005 <#3005>
Add a parser of `adb device -l` output, to extract a list of devices
with their serial, state and model.

PR #3005 <#3005>
In practice, it just tests if the serial contains a ':', which is
sufficient to distinguish ip:port from a real USB serial.

PR #3005 <#3005>
Select an adb device from the output of `adb device -l`.

PR #3005 <#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 <#3005>
The device serial is now retrieved from `adb devices -l`, `adb
get-serialno` is not called anymore.

PR #3005 <#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 <#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 <#3005>
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 <#3005>
@rom1v rom1v merged commit dc5276b into dev Feb 9, 2022
rom1v added a commit that referenced this pull request Mar 22, 2022
Emulators were wrongly considered as USB devices, so they were selected
using -d instead of -e (which was inconsistent with the adb behavior).

Refs #3005 <#3005>
Refs #3137 <#3137>
rom1v added a commit that referenced this pull request Mar 22, 2022
Emulators were wrongly considered as USB devices, so they were selected
using -d instead of -e (which was inconsistent with the adb behavior).

Refs #3005 <#3005>
Refs #3137 <#3137>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants