Commit graph

938 commits

Author SHA1 Message Date
Romain Vimont
854de9659a Do not inject Ctrl+v if clipboard sync failed
This prevents to paste the current Android clipboard, which would be
unexpected.

PR #2814 <https://github.com/Genymobile/scrcpy/pull/2814>
2021-11-23 21:15:05 +01:00
Romain Vimont
ea8028332c Synchronize computer-to-device empty clipboard
Set the device clipboard to empty string if necessary. Otherwise, the
current device clipboard will be pasted on Ctrl+v.

PR #2814 <https://github.com/Genymobile/scrcpy/pull/2814>
2021-11-23 21:14:49 +01:00
Romain Vimont
0427a981e5 Use UINT64_C macro for uint64_t constant in tests
A long constant might not be sufficient.
2021-11-21 22:57:33 +01:00
Romain Vimont
68eaee5bb0 Force adb forward if tunnel host/port is provided
Tunnel host and port are only meaningful in "adb forward" mode.

They indicate where the client must connect to communicate with the
server. In "adb reverse" mode, the client _listens_, it does not
_connect_.

Refs #2807 <https://github.com/Genymobile/scrcpy/pull/2807>
2021-11-21 22:37:52 +01:00
RipleyTom
7bdbde7363 Add options to configure tunnel host and port
In "adb forward" mode, by default, scrcpy connects to localhost:PORT,
where PORT is the local port passed to "adb forward". This assumes that
the tunnel is established on the local host with a local adb server
(which is the common case).

For advanced usage, add --tunnel-host and --tunnel-port to force the
connection to a different destination.

Fixes #2801 <https://github.com/Genymobile/scrcpy/issues/2801>
PR #2807 <https://github.com/Genymobile/scrcpy/pull/2807>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-11-21 22:37:52 +01:00
RipleyTom
52e5181c84 Add function to parse IPv4 addresses
PR #2807 <https://github.com/Genymobile/scrcpy/pull/2807>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-11-21 22:37:37 +01:00
Romain Vimont
ba547e3895 Configure feature test macros in meson
Refs #2807 <https://github.com/Genymobile/scrcpy/pull/2807>

Co-authored-by: RipleyTom <RipleyTom@users.noreply.github.com>
2021-11-21 00:20:11 +01:00
Romain Vimont
226f3b2c91 Add missing include config.h 2021-11-21 00:13:25 +01:00
Romain Vimont
6da6d905c2 Print scrcpy header first
Inconditionnally print the scrcpy version first, without using LOGI().

The log level is configured only after parsing the command line
parameters (it may be changed via -V), and command line parsing logs
should not appear before the scrcpy version.
2021-11-19 09:45:02 +01:00
Romain Vimont
b25404ee4b Print help to stdout
The output of -h/--help was printed on stderr, although it is not an
error.

Printing on stdout allows to pipe the result directly:

    scrcpy --help | less

Instead of (in bash):

    scrcpy --help |& less
2021-11-19 08:18:13 +01:00
Romain Vimont
4cfc1cd70a Assert that long options are correctly set 2021-11-19 08:06:23 +01:00
Romain Vimont
2fc80eae2d Simplify adb_tunnel
With the new adb functions, the static adb_tunnel functions become
unnecessary.
2021-11-19 07:25:03 +01:00
Romain Vimont
3fdbd994e0 Privatize low-level adb functions
Only expose the interruptible user-friendly API.
2021-11-19 07:25:03 +01:00
Romain Vimont
ce225f019a Use new user-friendly adb API
Replace the adb_exec_*() calls by the new adb functions to simplify.
2021-11-18 22:11:19 +01:00
Romain Vimont
b7559744a7 Expose new user-friendly adb functions
Expose interruptible adb functions which return the expected result
directly, without exposing the process (sc_pid) to the caller.
2021-11-18 22:08:15 +01:00
Romain Vimont
afb5a5e80f Rename adb functions to adb_exec_*
This paves the way to replace them by more user-friendly functions that
will call them internally.
2021-11-18 21:47:17 +01:00
Romain Vimont
84334cf7db Use sc_intr in file_handler
Replace manual interruption handling by the recent sc_intr mechanism.
2021-11-18 21:33:25 +01:00
Romain Vimont
0ba2686e1d Simplify file_handler
Call the target functions directly.
2021-11-18 19:46:47 +01:00
Romain Vimont
55648d4d64 Improve file_handler readability
Use local variables as short name aliases.
2021-11-18 19:46:40 +01:00
Romain Vimont
13fd693b50 Simplify adb_execute_p()
Only pass the stdout pipe as parameter, scrcpy never writes to stdin or
reads from stderr of an adb process.
2021-11-18 19:43:10 +01:00
Romain Vimont
0426ae885c Make "adb get-serialno" interruptible
All process executions must be interruptible, so that Ctrl+c reacts
immediately.
2021-11-18 19:41:41 +01:00
Romain Vimont
ea454e9cee Add interruptible function to read from pipe
This will avoid to block Ctrl+c if the process the pipe is read from
takes too much time.
2021-11-18 19:39:11 +01:00
Romain Vimont
cb65531533 Simplify sc_str_truncate()
Use strcspn() to get the prefix length directly.
2021-11-18 19:37:53 +01:00
Romain Vimont
9619ade706 Generalize string trunctation util function
Add an additional argument to let the client pass the possible end
chars.
2021-11-18 18:48:16 +01:00
Romain Vimont
f2781a8b6d Expose util function to truncate first line
Move the local implementation from adb functions to the string util
functions.
2021-11-18 18:48:16 +01:00
Romain Vimont
443cb14d6e Assume non-NULL serial in file_handler
The previous commit guarantees to always initialize the serial, so the
file_handle may assume it is never NULL.
2021-11-18 18:48:11 +01:00
Romain Vimont
b30c3a429f Always retrieve device serial
This allows to execute all adb commands with the specific -s parameter,
even if it is not provided by the user.

In practice, calling adb without -s works if there is exactly one device
connected. But some adb commands (for example "adb push" on drag & drop)
could be executed after another device is connected, so the actual
device serial must be known.
2021-11-18 18:32:15 +01:00
Romain Vimont
632bd5697b Add missing error handling
If "adb get-serialno" fails, attempting to read from the uninitialized
pipe is incorrect.
2021-11-18 18:32:15 +01:00
Romain Vimont
de50846905 Close process on check success
The interruptible version of the function to check process success
(sc_process_check_success_intr()) did not accept a close parameter to
avoid a race condition. But as the result, the processes were not closed
at all.

Add a close parameter, and close the process separately to avoid the
race condition.
2021-11-18 18:31:36 +01:00
Romain Vimont
9cb14b5166 Inherit only specific handles on Windows
To be able to communicate with a child process via stdin, stdout and
stderr, the CreateProcess() parameter bInheritHandles must be set to
TRUE. But this causes *all* handles to be inherited, including sockets.

As a result, the server socket was inherited by the process running adb
to execute the server on the device, so it could not be closed properly,
causing other scrcpy instances to fail.

To fix the issue, use an extended API to explicitly set the HANDLEs to
inherit:
 - <https://stackoverflow.com/a/28185363/1987178>
 - <https://devblogs.microsoft.com/oldnewthing/20111216-00/?p=8873>

Fixes #2779 <https://github.com/Genymobile/scrcpy/issues/2779>
PR #2783 <https://github.com/Genymobile/scrcpy/pull/2783>
2021-11-15 10:13:30 +01:00
Romain Vimont
9cb8766220 Factorize resource release after CreateProcess()
Free the wide characters string in all cases before checking for errors.
2021-11-15 07:49:01 +01:00
Romain Vimont
fd4ec784e0 Remove useless assignments on error
Leave the output parameter untouched on error.
2021-11-14 22:53:49 +01:00
Romain Vimont
52cebe1597 Fix Windows sc_pipe function names
The implementation name was incorrect (it was harmless, because they are
not used on Windows).
2021-11-14 22:41:38 +01:00
Romain Vimont
6a27062f48 Stop connection attempts if interrupted
If the interruptor is interrupted, every network call will fail, but the
retry-on-error mechanism must also be stopped.
2021-11-14 15:40:59 +01:00
Romain Vimont
739ff9dce0 Fix compilation errors with old SDL versions
SDL_PixelFormatEnum has been introduced in SDL 2.0.10:
<cc6a8ac87e>

SDL_PIXELFORMAT_BGR444 has been introduced in SDL 2.0.12:
<a1c11854f2>

Fixes #2777 <https://github.com/Genymobile/scrcpy/issues/2777>
PR #2781 <https://github.com/Genymobile/scrcpy/pull/2781>

Reviewed-by: Yu-Chen Lin <npes87184@gmail.com>
2021-11-14 15:37:30 +01:00
Romain Vimont
45b0f8123a Increase delay to inject HID on Ctrl+v
2 milliseconds turn out to be insufficient sometimes. It seems that 5
milliseconds is enough (and still not noticeable).
2021-11-14 01:23:06 +01:00
Romain Vimont
c1a34881d7 Use sc_ prefix for server 2021-11-14 01:23:05 +01:00
Romain Vimont
057c7a4df4 Move str_util to str
Simplify naming.
2021-11-14 01:22:22 +01:00
Romain Vimont
979ce64dc0 Improve string util API
Use prefixed names and improve documentation.
2021-11-14 01:22:22 +01:00
Romain Vimont
9a0bd545d5 Rename SC_INVALID_SOCKET to SC_SOCKET_NONE
For consistency with SC_PROCESS_NONE.
2021-11-14 01:22:22 +01:00
Romain Vimont
c4d008b96a Extract adb tunnel to a separate component
This simplifies the server code.
2021-11-14 01:22:22 +01:00
Romain Vimont
0d45c29d13 Move IPV4_LOCALHOST to net.h
This constant will be used from several files.
2021-11-14 01:22:22 +01:00
Romain Vimont
37c840a4c8 Interrupt on process terminated
Interrupt any blocking call on process terminated, like on
server_stop().

This allows to interrupt any blocking accept() with correct
synchronization without additional complexity.
2021-11-14 01:22:22 +01:00
Romain Vimont
f488cbd7e7 Make server interruptible
Use an interruptor to immediately wake up blocking calls on
server_stop().
2021-11-14 01:22:20 +01:00
Romain Vimont
40340509d9 Add interruptor utilities
Expose wrapper functions for interrupting blocking calls, for process
and sockets.
2021-11-13 22:54:18 +01:00
Romain Vimont
e0896142db Introduce interruptor tool
An interruptor instance will help to wake up a blocking call from
another thread (typically to terminate immediately on Ctrl+C).
2021-11-13 22:53:07 +01:00
Romain Vimont
0426708544 Run the server from a dedicated thread
Define server callbacks, start the server asynchronously and listen to
connection events to initialize scrcpy properly.

It will help to simplify the server code, and allows to run the UI event
loop while the server is connecting. In particular, this will allow to
receive SIGINT/Ctrl+C events during connection to interrupt immediately.
2021-11-13 10:19:52 +01:00
Romain Vimont
5b9c88693e Wait using a condition variable in server
Currently, server_stop() is called from the same thread as
server_connect_to(), so interruption may never happen.

This is a step to prepare executing the server from a dedicated thread.
2021-11-13 10:17:51 +01:00
Romain Vimont
a54dc8212f Reorder server functions
This will avoid forward declarations in future commits.
2021-11-13 10:16:35 +01:00
Romain Vimont
882e4cff5f Copy server params
This is a preliminary step necessary to move the server to a separate
thread.
2021-11-13 10:05:20 +01:00
Romain Vimont
9fa4d1cd4a Reorder server and server_params
This will allow to define a server_params field in server.
2021-11-13 10:05:20 +01:00
Romain Vimont
0bfa75a48b Split socket creation and connect/listen
This will allow to assign the socket to a variable before connecting or
listening, so that it can be interrupted from another thread.
2021-11-13 10:05:20 +01:00
Romain Vimont
ed19901db1 Set video and control sockets only on success
Store the video and control sockets only if server_connect_to() returns
successfully.
2021-11-13 10:05:01 +01:00
Romain Vimont
e69356c550 Initialize tunnel_enabled flag internally
Set the flag from the inner methods, to avoid bypassing the assignment
by mistake (on error for example).
2021-11-13 10:03:03 +01:00
Romain Vimont
03de9224fc Introduce process observer
Add a tool to easily observe process termination.

This allows to move this complexity out of the server code.
2021-11-13 10:02:23 +01:00
Romain Vimont
aa011832c1 Improve process API
Prefix symbols and constants names and improve documentation.
2021-11-12 22:44:37 +01:00
Romain Vimont
7e93abcf6d Factorize common impl of process_execute()
Both implementations are the same. Move them to the common process.c.
2021-11-12 22:44:37 +01:00
Romain Vimont
e80e6631e4 Remove duplicate function declaration
The function process_terminate() was declared twice.
2021-11-12 22:44:37 +01:00
Romain Vimont
fcc04f967b Improve file API
Prefix symbols and constants names and improve documentation.
2021-11-12 22:44:37 +01:00
Romain Vimont
d4c262301f Move functions from process to file
Move filesystem-related functions from process.[ch] to file.[ch].
2021-11-12 22:44:37 +01:00
Romain Vimont
be55e250ca Make screen_render() static
It is only used from screen.c.
2021-11-12 22:44:22 +01:00
Romain Vimont
7a733328bc Adapt help to terminal size
If the error stream is a terminal, and we can retrieve the terminal
size, wrap the help content according to the terminal width.
2021-11-11 15:22:39 +01:00
Romain Vimont
38332f683c Add util function to get terminal size 2021-11-11 15:22:39 +01:00
Romain Vimont
3f51a2ab43 Generate getopt params from option structures
Use the option descriptions to generate the optstring and longopts
parameters for the getopt_long() command.

That way, the options are completely described in a single place.
2021-11-11 14:59:34 +01:00
Romain Vimont
74ab0a4df8 Structure shortcuts help 2021-11-11 14:59:34 +01:00
Romain Vimont
f59e9e3cb0 Structure command line options help
It will allow to correctly print the help for the current terminal size
(even if for now it is hardcoded to 80 columns).
2021-11-11 14:59:34 +01:00
Romain Vimont
9ec3406568 Add line wrapper
Add a tool to wrap lines at words boundaries (spaces) to fit in a
specified number of columns, left-indented by a specified number of
spaces.
2021-11-11 14:55:53 +01:00
Romain Vimont
6dba1922c1 Add string buffer util
This will help to build strings incrementally.
2021-11-11 14:55:52 +01:00
Romain Vimont
570a003c39 Remove deprecated -T option
The short option -T is deprecated since v1.11. Only the long version
(--always-on-top) remains.
2021-11-07 21:35:57 +01:00
Romain Vimont
b62df7ee91 Remove deprecated -c option
The short option -c is deprecated since v1.11. Only the long version
(--crop) remains.
2021-11-07 21:35:53 +01:00
Romain Vimont
30d40f4e78 Document --power-off-on-close
The option was not documented.

Refs #824 <https://github.com/Genymobile/scrcpy/pull/824>
2021-11-07 19:27:53 +01:00
Romain Vimont
f489f7fcad Mention drag & drop for non-APK files in help 2021-11-07 18:51:22 +01:00
Romain Vimont
f65c3fde69 Fix typos in help 2021-11-07 18:50:24 +01:00
Romain Vimont
48fcfa96ab Add missing include "common.h" 2021-11-06 19:26:29 +01:00
Romain Vimont
676fa73d2c Wrap device name and size in a struct
As a benefit, this avoids to take care of the device name length on the
caller side.
2021-11-02 11:08:58 +01:00
Romain Vimont
58ea238fb2 Remove unnecessary variable
Test directly if a record filename is provided, without an intermediate
boolean variable.
2021-10-31 12:45:59 +01:00
Romain Vimont
13c4aa1a3b Disable synthetic mouse events from touch events
Touch events with id SDL_TOUCH_MOUSEID are ignored anyway, but it is
better not to generate them in the first place.
2021-10-31 12:45:59 +01:00
Romain Vimont
caf594c90e Split SDL initialization
Initialize SDL_INIT_EVENTS first (very quick) and SDL_INIT_VIDEO after
the server (quite long).
2021-10-31 12:45:59 +01:00
Romain Vimont
688477ff65 Move SDL initialization
Inline SDL initialization in scrcpy(). This will allow to split
minimal initialization and video initialization.
2021-10-31 12:45:59 +01:00
Romain Vimont
ac539e1312 Set SDL hints before initialization
In theory, some SDL hints should be initialized before calling
SDL_Init().
2021-10-31 12:45:59 +01:00
Romain Vimont
a57c7d3a2b Extract SDL hints
Set all SDL hints in a separate function.
2021-10-31 12:45:56 +01:00
Romain Vimont
d2d18466d4 Factorize SDL event push
Add a macro and inline function to call SDL_PushEvent() and log on error
(without actually handling the error, because there is nothing we could
do).
2021-10-30 22:36:56 +02:00
Romain Vimont
dae091e3ab Handle SDL_PushEvent() errors
Pushing an event to the main thread may fail. If this happens, log an
error, and try to recover when possible.
2021-10-30 20:25:20 +02:00
Romain Vimont
4c4381de4c Use sc_ prefix for size, position and point 2021-10-30 15:20:39 +02:00
Romain Vimont
06131ef634 Fix typo in clock comments 2021-10-29 12:21:34 +02:00
Romain Vimont
34eb10ea0b Define v4l2 option field only if HAVE_V4L2 2021-10-27 18:43:47 +02:00
Romain Vimont
27fa23846d Define default options as const struct
This is more readable than a macro, and we could ifdef some fields.
2021-10-27 18:43:47 +02:00
Romain Vimont
e4d5c1ce36 Move scrcpy option structs to options.h
This will allow to define symbols in options.c without all the
dependencies of scrcpy.c.
2021-10-27 18:43:47 +02:00
Romain Vimont
ac23bec144 Expose socket interruption
On Linux, socket functions are unblocked by shutdown(), but on Windows
they are unblocked by closesocket().

Expose net_interrupt() and net_close() to abstract these differences:
 - net_interrupt() calls shutdown() on Linux and closesocket() on
   Windows (if not already called);
 - net_close() calls close() on Linux and closesocket() on Windows (if
   not already called).

This simplifies the server code, and prevents a data race on close
(reported by TSAN) on Linux (but does not fix it on Windows):

    WARNING: ThreadSanitizer: data race (pid=836124)
      Write of size 8 at 0x7ba0000000d0 by main thread:
        #0 close ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1690 (libtsan.so.0+0x359d8)
        #1 net_close ../app/src/util/net.c:211 (scrcpy+0x1c76b)
        #2 close_socket ../app/src/server.c:330 (scrcpy+0x19442)
        #3 server_stop ../app/src/server.c:522 (scrcpy+0x19e33)
        #4 scrcpy ../app/src/scrcpy.c:532 (scrcpy+0x156fc)
        #5 main ../app/src/main.c:92 (scrcpy+0x622a)

      Previous read of size 8 at 0x7ba0000000d0 by thread T6:
        #0 recv ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:6603 (libtsan.so.0+0x4f4a6)
        #1 net_recv ../app/src/util/net.c:167 (scrcpy+0x1c5a7)
        #2 run_receiver ../app/src/receiver.c:76 (scrcpy+0x12819)
        #3 <null> <null> (libSDL2-2.0.so.0+0x84f40)
2021-10-27 18:41:58 +02:00
Romain Vimont
e5ea13770b Add socket wrapper
This paves the way to store an additional "closed" flag on Windows
to interrupt and close properly.
2021-10-26 22:49:57 +02:00
Romain Vimont
3eac212af1 Use net_send() from net_send_all()
This will make net_send_all() continue to work even if net_send()
behavior is changed.
2021-10-26 22:49:45 +02:00
Romain Vimont
3adff37c2d Use sc_ prefix for sockets
Rename:
 - socket_t to sc_socket
 - INVALID_SOCKET to SC_INVALID_SOCKET
2021-10-26 22:49:45 +02:00
Romain Vimont
eb6afe7669 Move net_init() and net_cleanup() upwards
These two functions are global, define them at the top of the
implementation file. This is consistent with the header file.
2021-10-26 22:49:45 +02:00
Romain Vimont
e4163321f0 Delay HID events on Ctrl+v
When Ctrl+v is pressed, a control is sent to the device to set the
device clipboard before injecting Ctrl+v.

With the InputManager method, it is guaranteed that the device
synchronization is executed before handling Ctrl+v, since the commands
are executed on the device in sequence.

However, HID are injected from the computer, so there is no such
guarantee. As a consequence, on Android, Ctrl+v triggers a paste with
the old clipboard content.

To workaround the issue, wait a bit (2 milliseconds) from the AOA
thread before injecting the event, to leave enough time for the
clipboard to be set before injecting Ctrl+v.
2021-10-26 21:30:04 +02:00
Romain Vimont
c96874b257 Synchronize HID keyboard state on first event
When an AOA HID keyboard is registered, CAPSLOCK and NUMLOCK are both
disabled, regardless of the state of the computer keyboard.

To synchronize the state, on first key event, inject CAPSLOCK and/or
NUMLOCK if necessary.
2021-10-26 21:30:04 +02:00
Romain Vimont
511356710d Retrieve device serial for AOA
The serial is necessary to find the correct Android device for AOA.

If it is not explicitly provided by the user via -s, then execute "adb
getserialno" to retrieve it.
2021-10-26 21:30:04 +02:00
Romain Vimont
d55015e4cf Expose function to get the device serial
Expose adb_get_serialno() to retrieve the device serial via the command
"adb getserialno".
2021-10-26 21:30:04 +02:00
Romain Vimont
0681480809 Add read_pipe_all()
Add a convenience function to read from a pipe until all requested data
has been read.
2021-10-26 21:30:04 +02:00
Romain Vimont
96b18dabaa Expose adb execution with redirection
Expose the redirection feature to the adb API.
2021-10-26 21:30:04 +02:00
Romain Vimont
eaf4afaad9 Add command execution with redirection
Expose command execution with pipes to stdin, stdout and stderr.

This will allow to read the result of adb commands.
2021-10-26 21:30:04 +02:00