1626 Commits

Author SHA1 Message Date
Romain Vimont
23ec073fc1 Implement HID gamepad
Implement the HID protocol for gamepads, that will be used in further
commits by the AOA and UHID gamepad processor implementations.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
131a170a4d Add util functions to write in little-endian
This will be helpful for writing HID values.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
6210b51dcc Handle SDL gamepad events
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.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>

Co-authored-by: Luiz Henrique Laurini <luizhenriquelaurini@gmail.com>
2024-09-13 22:03:02 +02:00
Romain Vimont
d24580f469 Discard unknown SDL events
Mouse and keyboard events with unknown button/keycode/scancode cannot be
handled properly. Discard them without forwarding them to the
keyboard or mouse processors.

This can happen for example if a more recent version of SDL introduces
new enum values.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
04a45e3f4b Fix HID comments
Fix typo and reference the latest version of "HID Usage Tables"
specifications.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
d82f4b35f7 Make AOA keyboard/mouse open error fatal
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.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
c1a81a99e2 Unregister all AOA devices automatically on exit
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.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
300ba3cb20 Make HID logs uniform
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
4a50e5ac83 Add AOA open/close verbose logs
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
9306daa609 Introduce hid_open and hid_close events
This allows to handle HID open/close reports at the same place as HID
input reports (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.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
94e0db4c74 Rename hid_event to hid_input
The sc_hid_event structure represents HID input data. Rename it so that
we can add other hid event structs without confusion.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
952fc75676 Make AOA open and close asynchronous
For AOA keyboard and mouse, only input reports were asynchronous.
Register/unregister were called from the main thread.

This had the benefit to fail immediately if the AOA registration failed,
but we want to open/close AOA devices dynamically in order to add
gamepad support.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
33ddccf9f6 Reorder AOA functions
This will allow sc_aoa_setup_hid() to compile even when
sc_aoa_unregister_hid() will be made static.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
90216c2082 Refactor AOA handling
Extract event processing to a separate function.

This will make the code more readable when more event types will be
added.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
43be63ea98 Move HID ids to common HID code
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.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
fd17b929ba Fix HID mouse header guard
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
b2107bb833 Add missing SC_ prefix for HID mouse event size
PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
57051b57ea Remove duplicate definition SC_HID_MAX_SIZE
This constant is defined in hid_event.h.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
0c4de3b37d Fail on AOA keyboard/mouse initialization error
If the AOA keyboard or the AOA mouse fails to be initialized, this is a
fatal error.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
4963b468cb Introduce non-droppable control messages
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 all further UHID_INPUT messages invalid.
Therefore, mark these messages as non-droppable.

A non-droppable event is queued anyway (resizing the queue if
necessary, unless the allocation fails).

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
df8fdfcc82 Remove atomics from keyboard_uhid
The UHID output callback is now called from the same (main) thread as
the process_key() function.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
a12106044c Process UHID outputs events from the main thread
This will guarantee that the callbacks of UHID devices implementations
will always be called from the same (main) thread.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
557bc69265 Set clipboard from the main thread
The clipboard changes from the device are received from a separate
thread, but they must be handled from the main thread.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
10250dce65 Add mechanism to execute code on the main thread
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).

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
73d722d4bf Expose main thread id
This will allow to assert that a function is called from the main
thread.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:02 +02:00
Romain Vimont
ca08d45bd7 Extract sc_push_event()
Expose a convenience function to push an event without args to the main
thread.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:01 +02:00
Romain Vimont
5317492225 Store events numbers in an enum
This avoids to manually set an explicit value for each item.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
2024-09-13 22:03:01 +02:00
Romain Vimont
cce886d94a Fix deprecated references in scrcpy manpage
The options --hid-keyboard and --hid-mouse do not exist anymore. They
have been replaced by --keyboard=XXX and --mouse=XXX.
2024-09-13 22:03:01 +02:00
Romain Vimont
68982c73da Do not send uninitialized HID event
If the function returns false, then there is nothing to send.
2024-09-13 22:03:01 +02:00
Romain Vimont
8d4ea2bd37 Fix compilation with -Dusb=false
UHID does not depend on USB support, so the struct sc_uhid_devices must
always be defined.
2024-09-13 22:03:01 +02:00
Romain Vimont
265a15e0b1 Accept float values for --max-fps
Android accepts a float value, there is no reason to limit the option
to be an integer.

In particular, it allows to capture at a rate lower than 1 fps. For
example, to capture 1 frame every 5 seconds:

    scrcpy --video-source=camera --max-fps=0.2

It was already possible to pass a float manually:

    scrcpy --video-source=camera \
        --video-codec-options=max-fps-to-encoder:float=0.2

But accepting a float directly for --max-fps is more convenient.

Refs <https://developer.android.com/reference/android/media/MediaFormat#KEY_MAX_FPS_TO_ENCODER>
2024-09-13 22:02:25 +02:00
Romain Vimont
bec3321fff Validate server arguments
Some command line arguments are passed as is to "adb shell". Therefore,
they must not contain special shell characters.
2024-09-13 19:53:05 +02:00
Romain Vimont
dea1fe3386 Validate crop and video size
A video width or height of 0 triggered an assert.

Fail explicitly instead: the server may actually send this size in
practice (for example on cropping with small dimensions, even if the
requested crop size is not 0).
2024-09-13 19:48:55 +02:00
Romain Vimont
a7cae59578 Improve delay buffer startup
The delay buffer clock estimates the clock offset between the PTS and
the frame decoded date using an "Exponentially Weighted Moving Average"
(EWMA).

But for the first frames, the clock have less than SC_CLOCK_RANGE
points to average. Since the timing for the first frames are typically
the worst ones, give more weight to the last point for the estimation.

Once SC_CLOCK_RANGE points are available (i.e. when SC_CLOCK_RANGE ==
clock->range), the new estimation is equivalent to the previous version.
2024-09-12 11:06:13 +02:00
Romain Vimont
f089ea67e1 Add missing flag initialization
The delay buffer `stopped` field was not initialized.

Since it practice the unique instance of sc_delay_buffer is initialized
in static memory, the flag was initialized to false as a side effect.

But with commit fd0f432e877153d83ed435474fb7b04e41de4269, in debug mode
only, the delay buffer was broken.
2024-09-11 15:41:49 +02:00
Romain Vimont
63ced79842 Reverse NDEBUG conditions
By default, these specific debug logs are disabled.

Make the ifdef condition less confusing.
2024-09-11 15:41:29 +02:00
Romain Vimont
33a8c39beb Fix local NDEBUG define
The struct definition and the implementation did not use the same NDEBUG
constant.
2024-09-11 11:26:07 +02:00
Romain Vimont
903a5aaaf5 Replace "could not" by "cannot" where appropriate
"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.
2024-09-09 08:24:52 +02:00
yangfl
dd47cefa47 Fix typos
Refs <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1077968#27>
PR #5171 <https://github.com/Genymobile/scrcpy/pull/5171>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2024-08-05 16:13:02 +02:00
Romain Vimont
cc41115625 Bump version to 2.6.1 2024-08-02 22:32:04 +02:00
Romain Vimont
52136268ef Bump version to 2.6 2024-08-01 18:15:59 +02:00
Romain Vimont
5d2441d198 Upgrade SDL (2.30.5) for Windows 2024-08-01 18:15:37 +02:00
Romain Vimont
071d459ad7 Fix --no-audio
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.
2024-07-29 20:03:44 +02:00
Romain Vimont
127a271d34 Switch audio source if audio-dup is set
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>
2024-07-19 17:48:39 +02:00
Romain Vimont
31116a60d7 Add --audio-dup
Add an option to duplicate audio on the device, compatible with the new
audio playback capture (--audio-source=playback).

Fixes #3875 <https://github.com/Genymobile/scrcpy/issues/3875>
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>
2024-07-19 17:48:39 +02:00
Romain Vimont
a10f8cd798 Add audio playback capture method
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>
2024-07-19 17:48:39 +02:00
Romain Vimont
c57a0512ba Add assertions
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.
2024-07-16 21:31:31 +02:00
Romain Vimont
9989668226 Add mouse secondary bindings
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>
2024-07-11 12:04:09 +02:00
Romain Vimont
6baea57987 Track mouse buttons state manually
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>
2024-07-11 12:04:09 +02:00
Romain Vimont
86b8286217 Remove unused virtual mouse
PR #5076 <https://github.com/Genymobile/scrcpy/pull/5076>
2024-07-11 12:04:09 +02:00