For convenience, short options were added to select UHID input modes:
- -K for --keyboard=uhid
- -M for --mouse=uhid
- -G for --gamepad=uhid
In OTG mode, UHID is not available, so the short options should select
AOA instead.
Similar to UHID keyboard and mouse, but for gamepads.
Can be enabled with --gamepad=uhid or -G.
It is not enabled by default because not all devices support UHID
(there is a permission error on old Android versions).
This message will be sent on gamepad disconnection.
Contrary to keyboard and mouse, which are registered once and are
unregistered when scrcpy exists, each gamepad is mapped with its own HID
id, and they can be plugged/unplugged dynamically.
Trigger SDL_CONTROLLERDEVICEADDED for all gamepads already connected
when scrcpy starts. We want to handle both the gamepads initially
connected and the gamepads connected while scrcpy is running.
This is not racy, because this event may not trigged automatically until
SDL events are "pumped" (SDL_PumpEvents/SDL_WaitEvent).
Introduce a gamepad processor trait, similar to the keyboard processor
and mouse processor traits.
Handle gamepad events received from SDL, convert them to scrcpy-specific
gamepad events, and forward them to the gamepad processor.
Further commits will provide AOA and UHID implementations of the gamepad
processor trait.
Co-authored-by: Luiz Henrique Laurini <luizhenriquelaurini@gmail.com>
Now that the AOA open/close are asynchronous, an open error did not make
scrcpy exit anymore.
Add a mechanism to exit if the AOA device could not be opened
asynchronously.
Pushing a close event from the keyboard_aoa or mouse_aoa implementation
was racy, because the AOA thread might be stopped before these events
were processed.
Instead, keep the list of open AOA devices to close them automatically
from the AOA thread before exiting.
This allows to handle HID open/close at the same place as HID input
events (in the HID layer).
This will be especially useful to manage HID gamepads, to avoid
implementing one part in the HID layer and another part in the gamepad
processor implementation.
For AOA keyboard and mouse, only input events were asynchronous.
Register/unregister were called from the main thread.
This had the benefit to fail immediately if the AOA registration failed,
but to support gamepads we want to open/close AOA devices dynamically.
Also, it is better to avoid USB I/O from the main thread.
The HID ids (accessory ids or UHID ids) were defined by the keyboard and
mouse implementations.
Instead, define them in the common HID part, and make that id part of
the sc_hid_event.
This prepares the introduction of gamepad support, which will handle
several gamepads (and ids) in the common HID gamepad code.
Control messages are queued from the main thread and sent to the device
from a separate thread.
When the queue is full, messages are just dropped. This avoids to
accumulate too much delay between the client and the device in case of
network issue.
However, some messages should not be dropped: for example, dropping a
UHID_CREATE message would make invalid all further UHID_INPUT messages.
Therefore, mark these messages as non-droppable.
A non-droppable event is queued anyway (resizing the queue if
necessary, unless the allocation fails).
This allows to schedule a runnable to be executed on the main thread,
until the event loop is explicitly terminated.
It is guaranteed that all accepted runnables will be executed (this
avoids possible memory leaks if a runnable owns resources).
"Could not" implies that the system tried to disable the option but
encountered an issue or failure.
"Cannot" indicates a rule or restriction, meaning it's not possible to
perform the action at all.
By default, the audio source is initialized to SC_AUDIO_SOURCE_AUTO, and
is "resolved" only if audio is enabled.
But the server arguments were built assuming that the audio source was
never SC_AUDIO_SOURCE_AUTO (even with audio disabled), causing a crash.
Regression introduced by a10f8cd798023f858796b023cb846fa2184ad2c7.
Automatically switch implicit audio source to "playback" if --audio-dup
is passed.
This allows to run:
scrcpy --audio-dup
without specifying explicitly:
scrcpy --audio-source=playback --audio-dup
PR #5102 <https://github.com/Genymobile/scrcpy/pull/5102>
Add a new method to capture audio playback.
It requires Android 13 (where the Shell app has MODIFY_AUDIO_ROUTING
permission).
The main benefit is that it supports keeping audio playing on the device
(implemented in a further commit).
Fixes#4380 <https://github.com/Genymobile/scrcpy/issues/4380>
PR #5102 <https://github.com/Genymobile/scrcpy/pull/5102>
Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
Passing an unknown enum value to convert them to string would return
NULL without any error, possibly causing undefined behavior later.
Add assertions to catch such programming errors early.
Add secondary bindings (Shift+click) for mouse buttons.
In addition to:
--mouse-bind=xxxx
It is now possible to pass a sequence of secondary bindings:
--mouse-bind=xxxx:xxxx
<--> <-->
primary secondary
bindings bindings
If the second sequence is omitted, then it is the same as the first one.
By default, for SDK mouse, primary bindings trigger shortcuts and
secondary bindings forward all clicks.
For AOA and UHID, the default bindings are reversed: all clicks are
forwarded by default, whereas pressing Shift+click trigger shortcuts.
--mouse-bind=bhsn:++++ # default for SDK
--mouse-bind=++++:bhsn # default for AOA and UHID
Refs 035d60cf5d3f4c83d48735b4cb4cd108a5b5f413
Refs f5e6b8092afd82bab402e7c2c3d00b1719f9bb57
Fixes#5055 <https://github.com/Genymobile/scrcpy/issues/5055>
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
The buttons state was tracked by SDL_GetMouseState(), and scrcpy applied
a mask to ignore buttons used for shortcuts.
Instead, track the buttons actually pressed (ignoring shortcuts)
manually, to prepare the introduction of more dynamic mouse shortcuts.
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
For pinch-to-zoom, rotation and tilt simulation, always use a finger
source (instead of a mouse) for both pointers (the real one and the
simulated one).
A "virtual" mouse does not work on all devices (e.g. on Pixel 8).
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>