Commit Graph

448 Commits

Author SHA1 Message Date
Romain Vimont
2380879376 Remove unused IOException
IOException may not be thrown from this method.
2023-03-12 02:04:58 +01:00
Romain Vimont
238ab872ba Pass video size as codec metadata
On initial connection, scrcpy sent some device metadata:
 - the device name (to be used as window title)
 - the initial video size (before any frame or even SPS/PPS)

But it is better to provide the initial video size as part as the video
stream, so that it can be demuxed and exposed via AVCodecContext to
sinks.

This avoids to pass an explicit "initial frame size" for the screen, the
recorder and the v4l2 sink.
2023-03-11 15:57:25 +01:00
Romain Vimont
aa1efbc35c Rename sendCodecId to sendCodecMeta
This will allow the codec header to contain more than the codec id.
2023-03-11 15:57:25 +01:00
Romain Vimont
4a25f3e53b Print info logs to stdout
All server logs were printed to stdout, while all client logs were
printed to stderr.

Instead, use stderr for warnings and errors, stdout for the others:
 - stdout: verbose, debug, info
 - stderr: warn, error
2023-03-10 22:22:15 +01:00
Romain Vimont
bb56472d4e Print server logs and newline in one call
System.out.println() first prints the message, then the new line.
Between these two calls, the client might print a message, breaking
formatting.

Instead, call System.out.print() with '\n' appended to the message.
2023-03-10 22:22:15 +01:00
Romain Vimont
66b6c06443 Add raw audio recorder
Add an alternative AudioRecorder to stream raw packets without encoding.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
dc228eaad0 Extract async processor interface
On the server side, several components are started, stopped and joined.
Extract an interface to handle them generically.

This will help to support both encoded and raw audio stream, because
they will be two different concrete components, but implementing the
same interface.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
65cc9d765d Extract audio capture
The audio capture was implemented in AudioEncoder.

In order to reuse it without encoding, extract it to a separate class.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Simon Chan
de40cac6ad Add workaround to capture audio on Android 11
On Android 11, it is possible to start the capture only when the running
app is in foreground. But scrcpy is not an app, it's a Java application
started from shell.

As a workaround, start an existing Android shell existing activity just
to start the capture, then close it immediately.

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

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-03-10 22:22:15 +01:00
Romain Vimont
a205ff6c8b Log display sizes in display list
This is more convenient than just the display id alone.
2023-03-10 22:22:15 +01:00
Romain Vimont
b65301f672 Add --list-displays
Add an option to list the device displays properly.
2023-03-10 22:22:15 +01:00
Romain Vimont
2596ca02f0 Move log message helpers to LogUtils
This class will also contain other log helpers.
2023-03-10 22:22:15 +01:00
Romain Vimont
50d56a9a2b Quit on audio configuration failure
When audio capture fails on the device, scrcpy continues mirroring the
video stream. This allows to enable audio by default only when
supported.

However, if an audio configuration occurs (for example the user
explicitly selected an unknown audio encoder), this must be treated as
an error and scrcpy must exit.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
9196dc1563 Add --list-encoders
Add an option to list the device encoders properly.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
f9960e959f Add --audio-encoder
Similar to --video-encoder, but for audio.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
6f332a2bc7 Extract unknown encoder error message
This will allow to reuse the same code for audio encoder selection.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
b03c864c70 Add --audio-codec-options
Similar to --video-codec-options, but for audio.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
58cf8e5401 Extract application of codec options
This will allow to reuse the same code for audio codec options.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
4601735e51 Add support for AAC audio codec
Add option --audio-codec=aac.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
839b842aa7 Add --audio-codec
Introduce the selection mechanism. Alternative codecs will be added
later.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
0870b8c8be Add --audio-bit-rate
Add an option to configure the audio bit-rate.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
8e640dc90f Disable MethodLength checkstyle on createOptions()
This method will grow as needed to initialize options.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
e694619d53 Rename --encoder to --video-encoder
This prepares the introduction of --audio-encoder.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
31555fa530 Rename --codec-options to --video-codec-options
This prepares the introduction of --audio-codec-options.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
9087e85c3f Rename --bit-rate to --video-bit-rate
This prepares the introduction of --audio-bit-rate.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
cee40ca047 Rename --codec to --video-codec
This prepares the introduction of --audio-codec.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
80c0780b77 Disable audio before Android 11
The permission "android.permission.RECORD_AUDIO" has been added for
shell in Android 11.

Moreover, on lower versions, it may make the server segfault on the
device (happened on a Nexus 5 with Android 6.0.1).

Refs <4feeee8891%5E%21/>
PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
13a3395a33 Disable audio on initialization error
By default, audio is enabled (--no-audio must be explicitly passed to
disable it).

However, some devices may not support audio capture (typically devices
below Android 11, or Android 11 when the shell application is not
foreground on start).

In that case, make the server notify the client to dynamically disable
audio forwarding so that it does not wait indefinitely for an audio
stream.

Also disable audio on unknown codec or missing decoder on the
client-side, for the same reasons.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
15556d1f3b Extract OPUS extradata
For OPUS codec, FFmpeg expects the raw extradata, but MediaCodec wraps
it in some structure.

Fix the config packet to send only the raw extradata.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
7cf5cf5875 Use a streamer to send the audio stream
Send each encoded audio packet using a streamer.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
5eed2c52c2 Encode recorded audio on the device
For now, the encoded packets are just logged into the console.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
464a35b05e Make streamer more generic
Expose a method to write a packet from raw metadata (without
BufferInfo).
2023-03-10 22:22:15 +01:00
Simon Chan
11d32616a9 Capture device audio
Create an AudioRecorder to capture the audio source REMOTE_SUBMIX.

For now, the captured packets are just logged into the console.

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

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-03-10 22:22:15 +01:00
Simon Chan
e841241a8e Add a new socket for audio stream
When audio is enabled, open a new socket to send the audio stream from
the device to the client.

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

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-03-10 22:22:15 +01:00
Simon Chan
3cf03e4a4b Add --no-audio option
Audio will be enabled by default (when supported). Add an option to
disable it.

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

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-03-10 22:22:15 +01:00
Romain Vimont
8487ddba64 Use FakeContext for Application instance
This will expose the correct package name and UID to the application
context.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
84ba6435bb Use shell package name for workarounds
For consistency.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
42285ae869 Use ROOT_UID from FakeContext
Remove USER_ID from ServiceManager, and replace it by a constant in
FakeContext.

This is the same as android.os.Process.ROOT_UID, but this constant has
been introduced in API 29.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
820189b6a6 Use PACKAGE_NAME from FakeContext
Remove duplicated constant.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
9a815ceba8 Use AttributionSource from FakeContext
FakeContext already provides an AttributeSource instance.

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

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2023-03-10 22:22:15 +01:00
Simon Chan
a5541b3476 Add a fake Android Context
Since scrcpy-server is not an Android application (it's a java
executable), it has no Context.

Some features will require a Context instance to get the package name
and the UID. Add a FakeContext for this purpose.

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

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-03-10 22:22:15 +01:00
Romain Vimont
10ef8da95d Improve error message for unknown encoder
The provided encoder name depends on the selected codec. Improve the
error message and the suggestions.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
90d88a6927 Rename "codec" variable to "mediaCodec"
This will allow to use "codec" for the Codec type.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
10ce0f376a Make streamer independent of codec type
Rename VideoStreamer to Streamer, and extract a Codec interface which
will also support audio codecs.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
2023-03-10 22:22:15 +01:00
Romain Vimont
c226797991 Pass all args to ScreenEncoder constructor
There is no good reason to pass some of them in the constructor and some
others as parameters of the streamScreen() method.
2023-03-10 22:22:15 +01:00
Romain Vimont
ae9b08b905 Move screen encoder initialization
This prepares further refactors.
2023-03-10 22:22:15 +01:00
Romain Vimont
51628201b7 Write streamer header from ScreenEncoder
The screen encoder is responsible for writing data to the video
streamer.
2023-03-10 22:22:15 +01:00
Romain Vimont
ae29e5b562 Use VideoStreamer directly from ScreenEncoder
The Callbacks interface notifies new packets. But in addition, the
screen encoder will need to write headers on start.

We could add a function onStart(), but for simplicity, just remove the
interface, which brings no value, and call the streamer directly.

Refs 87972e2022
2023-03-10 22:22:15 +01:00
Romain Vimont
5b2ec66222 Simplify error handling on socket creation
On any error, all previously opened sockets must be closed.

Handle these errors in a single catch-block. Currently, there are only 2
sockets, but this will simplify even more with more sockets.

Note: this commit is better displayed with --ignore-space-change (-b).
2023-03-10 22:22:15 +01:00
Romain Vimont
b43938fa66 Do not print stacktraces when unnecessary
User-friendly error messages are printed on specific configuration
exceptions. In that case, do not print the stacktrace.

Also handle the user-friendly error message directly where the error
occurs, and print multiline messages in a single log call, to avoid
confusing interleaving.
2023-03-10 22:22:15 +01:00
Romain Vimont
14a85fd61e Silence lint warning about constant in API 29
MediaFormat.MIMETYPE_VIDEO_AV1 has been added in API 29, but it is not
a problem to inline the constant in older versions.
2023-03-03 11:13:48 +01:00
Romain Vimont
ebecbe6bc6 Fix inconsistent quotes
The encoder name started with a simple quote but ended with a
double quote. Use a single quote for both.
2023-02-19 16:18:19 +01:00
Romain Vimont
d5dff239c8 Suggest commands with an explicit '=' 2023-02-19 16:18:19 +01:00
Romain Vimont
5cf86ef7ff Move finally-block to fix deadlock on stop
DesktopConnection implements Closeable, so it is implicitly closed after
its try-with-resources block. Closing the DesktopConnection shutdowns
the sockets, so it is necessary in particular to wake up blocking read()
calls from the controller.

But the controller thread was joined before the DesktopConnection was
closed, causing a deadlock. To fix the problem, join the controller
thread only after the DesktopConnection is closed.

Refs 400a1c69b1
2023-02-19 15:59:05 +01:00
Romain Vimont
f4e7085c34 Log non-EPIPE I/O exceptions
On close, the client closes the socket. This wakes up socket blocking
calls on the server-side, by throwing an exception. Since this exception
is expected, it was not logged.

However, other IOExceptions might occur, which must not be ignored. For
that purpose, log only IOException when they are not caused by an EPIPE
error.
2023-02-17 08:33:16 +01:00
Romain Vimont
439a1fd4ed Rename 'uid' to 'scid'
A random identifier is generated to differentiate multiple running
scrcpy instances. Rename it from 'uid' to 'scid' (scrcpy id) not to
confuse it with Linux UID.

Fixes #3729 <https://github.com/Genymobile/scrcpy/issues/3729>
Refs 4315be1648
2023-02-11 09:58:40 +01:00
Romain Vimont
45b2e6db5c Log component stopped in finally clause
The message must be logged even when no exception occurs.
2023-02-10 19:06:17 +01:00
Romain Vimont
400a1c69b1 Join all threads before end of main
Some calls from separate threads may throw exceptions once the main()
method has returned.
2023-02-10 19:04:56 +01:00
Romain Vimont
6524e90c68 Remove unused constant
This line was committed by error.

Refs 3e517cd40e
2023-02-07 23:11:42 +01:00
Romain Vimont
f2dee20a20 Set power mode on all physical displays
Android 10 and above support multiple physical displays. Apply power
mode to all of them.

Fixes #3716 <https://github.com/Genymobile/scrcpy/issues/3716>
2023-02-06 11:07:14 +01:00
Romain Vimont
d2dce51038 Add support for AV1
Add option --codec=av1.

PR #3713 <https://github.com/Genymobile/scrcpy/pull/3713>
2023-02-06 11:00:49 +01:00
Romain Vimont
4342c5637d Add support for H265
Add option --codec=h265.

PR #3713 <https://github.com/Genymobile/scrcpy/pull/3713>
Fixes #3092 <https://github.com/Genymobile/scrcpy/issues/3092>
2023-02-06 11:00:49 +01:00
Romain Vimont
3e517cd40e Add option to select video codec
Introduce the selection mechanism. Alternative codecs will be added in
further commits.

PR #3713 <https://github.com/Genymobile/scrcpy/pull/3713>
2023-02-06 10:58:45 +01:00
Romain Vimont
87972e2022 Extract video streaming to a separate class
ScreenEncoder handled both capture/encoding and sending over the
network.

Move the streaming part to a separate VideoStreamer.
2023-02-03 12:31:28 +01:00
Romain Vimont
3aac74e9e9 Move variable assignment
Computing eof flag is not necessary if rotation changed.
2023-02-03 12:31:28 +01:00
Romain Vimont
1c82c3923d Compute relative PTS on the client-side
The PTS received from MediaCodec are expressed relative to an arbitrary
clock origin. We consider the PTS of the first frame to be 0, and the
PTS of every other frame is relative to this first PTS (note that the
PTS is only used for recording, it is ignored for mirroring).

For simplicity, this relative PTS was computed on the server-side.

To prepare support for multiple stream (video and audio), send the
packet with its original PTS, and handle the PTS offset on the
client-side (by the recorder).

Since we can't know in advance which stream will produce the first
packet with the lowest PTS (a packet received later on one stream may
have a PTS lower than a packet received earlier on another stream),
computing the PTS on the server-side would require unnecessary waiting.
2023-02-03 12:31:28 +01:00
Romain Vimont
36d656e91f Improve workarounds call comments 2023-02-03 12:31:28 +01:00
Romain Vimont
bdbf1f4eb7 Move Workarounds call
Workarounds are not specific to the screen encoder.

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2023-02-03 12:31:28 +01:00
Romain Vimont
4177de5880 Do not expose controller threads
The way the controller executes its events asynchronously is an
implementation detail.
2023-02-03 12:31:28 +01:00
Simon Chan
9b286ec8a7 Inject additional ACTION_BUTTON_* events for mouse
On mouse click events:
 - the first button pressed must first generate ACTION_DOWN;
 - all button pressed (including the first one) must generate
   ACTION_BUTTON_PRESS;
 - all button released (including the last one) must generate
   ACTION_BUTTON_RELEASE;
 - the last button released must in addition generate ACTION_UP.

Otherwise, Chrome does not work properly.

Fixes #3635 <https://github.com/Genymobile/scrcpy/issues/3635>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-01-30 20:57:54 +01:00
Simon Chan
8c5c55f9e1 Fix mouse pointer state update
If the pointer is a mouse, the pointer is UP only when no buttons are
pressed (not when a button is released, because there might be other
buttons still pressed).

Refs #3635 <https://github.com/Genymobile/scrcpy/issues/3635>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-01-30 20:57:54 +01:00
Simon Chan
0afef0c634 Forward action button to device
On click event, only the whole buttons state was passed to the device.
In addition, on ACTION_DOWN and ACTION_UP, pass the button associated to
the action.

Refs #3635 <https://github.com/Genymobile/scrcpy/issues/3635>

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-01-30 20:57:54 +01:00
Romain Vimont
07806ba915 Retry on spurious error
MediaCodec may fail spuriously, typically when stopping an encoding and
starting a new one immediately (for example on device rotation).

In that case, retry a few times, in many cases it should work.

Refs #3693 <https://github.com/Genymobile/scrcpy/issues/3693>
2023-01-30 20:55:51 +01:00
Romain Vimont
a52053421a Extract retry handling
Move the code to downscale and retry on error out of the catch-block.

Refs 26b4104844
2023-01-29 14:49:36 +01:00
Romain Vimont
a9b2697f3e Move local variables declarations
This makes it clear that these local variables are only passed to
setDisplaySurface().
2023-01-27 22:43:16 +01:00
Romain Vimont
b53d2c66e0 Remove useless setSize() method
Inline its content. It makes the logic of internalStreamScreen() more
readable (it reduces the number of indirections).
2023-01-27 22:39:28 +01:00
Romain Vimont
6cccf3ab2a Remove useless configure() method
Inline its single call.
2023-01-27 22:38:37 +01:00
Romain Vimont
52f85fd6f1 Keep the same MediaCodec instance across sessions
Calling codec.reset() is sufficient.
2023-01-27 22:31:09 +01:00
Romain Vimont
91c69ad95c Remove useless destroyDisplay() method
The method made exactly one simple call. Just make the call directly.
2023-01-27 22:28:11 +01:00
Romain Vimont
75d7c01a0c Keep the same display binder across sessions
Do not destroy/recreate the display when starting a new encoding session
(on device rotation for example).
2023-01-27 22:26:01 +01:00
Romain Vimont
74d32e612d Terminate loop explicitly on interrupted
Make explicit that the loop terminates when the current thread is
interrupted.
2023-01-27 22:20:35 +01:00
Romain Vimont
bdba554118 Use Java lambdas where possible 2023-01-27 22:16:36 +01:00
Romain Vimont
8cbbcc939f Add missing final modifiers 2023-01-27 22:08:17 +01:00
Romain Vimont
b22810b17c Use try-with-resources
Replace an explicit try-finally by a try-with-resources block.
2023-01-27 21:59:26 +01:00
Romain Vimont
4315be1648 Use random name for device socket
For the initial connection between the device and the computer, an adb
tunnel is established (with "adb reverse" or "adb forward").

The device-side of the tunnel is a local socket having the hard-coded
name "scrcpy". This may cause issues when several scrcpy instances are
started in a few seconds for the same device, since they will try to
bind the same name.

To avoid conflicts, make the client generate a random UID, and append
this UID to the local socket name ("scrcpy_01234567").
2023-01-27 21:51:59 +01:00
Pawel Jasinski
c7b1d0ea9a Force mouse source when --forward-all-clicks
Right click and middle click require the source device to be a mouse,
not a touchscreen. Therefore, the source device was changed only when a
button other than the primary button was pressed (see
adc547fa6e).

However, this led to inconsistencies between the ACTION_DOWN when a
secondary button is pressed (with a mouse as source device) and the
matching ACTION_UP when the secondary button is released (with a
touchscreen as source device, because then there is no button pressed).

To avoid the problem in all cases, force a mouse as source device when
--forward-all-clicks is set.

Concretely, for mouse events in --forward-all-clicks mode:
 - device source is set to InputDevice.SOURCE_MOUSE;
 - motion event toolType is set to MotionEvent.TOOL_TYPE_MOUSE;

Otherwise (when --forward-all-clicks is unset, or for real touch
events), finger events are injected:
 - device source is set to InputDevice.SOURCE_TOUCHSCREEN;
 - motion event toolType is set to MotionEvent.TOOL_TYPE_FINGER.

Fixes #3568 <https://github.com/Genymobile/scrcpy/issues/3568>
PR #3579 <https://github.com/Genymobile/scrcpy/pull/3579>

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2022-12-22 11:26:26 +01:00
Romain Vimont
82cb8ab870 Adapt ClipboardManager for Android 13
A new "attributionTag" parameter has been added to the methods
getPrimaryClip(), setPrimaryClip() and addPrimaryClipChangedListener()
of IClipboard.aidl.

Refs <0e3e509b3b%5E%21/>

Fixes #3497 <https://github.com/Genymobile/scrcpy/issues/3497>
2022-12-21 13:28:22 +01:00
SeungHoon Han
597703b62e Fix DisplayInfo parsing for Android Q
The DisplayInfo dump format has slightly changed in AOSP:
<1039ea50f3>

PR #3573 <https://github.com/Genymobile/scrcpy/pull/3573>
Ref #3416 <https://github.com/Genymobile/scrcpy/pull/3416>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2022-11-12 18:15:45 +01:00
Romain Vimont
40644994e8 Make ServiceManager and Settings methods static
There were exactly one instance of ServiceManager and Settings, stored
in Device.

Since a Device instance is not created by the CleanUp executable, it was
not straightforward to call wrapper methods on cleanup.

Remove this artificial restriction and expose them publicly via static
methods (this is equivalent to expose a singleton, but less verbose).
2022-10-02 17:57:35 +02:00
SeungHoon Han
949b64dff2 Add fallback to get DisplayInfo
PR #3416 <https://github.com/Genymobile/scrcpy/pull/3416>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2022-09-25 16:22:51 +02:00
Simon Chan
57056d078d Use precise scrolling values
Since SDL 2.0.18, the amount scrolled horizontally or vertically is
exposed as a float (between 0 and 1). Forward a precise value to the
Android device when possible.

Refs <https://wiki.libsdl.org/SDL_MouseWheelEvent>
Fixes #3363 <https://github.com/Genymobile/scrcpy/issues/3363>
PR #3369 <https://github.com/Genymobile/scrcpy/pull/3369>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2022-08-28 15:23:08 +02:00
Romain Vimont
1f138aef41 Add conversion from float to fixed-point i16
To encode float values between -1 and 1.

PR #3369 <https://github.com/Genymobile/scrcpy/pull/3369>
2022-08-28 15:23:08 +02:00
Romain Vimont
3848ce86f1 Extract conversion from u16 fixed-point to float
PR #3369 <https://github.com/Genymobile/scrcpy/pull/3369>
2022-08-28 15:23:08 +02:00
Romain Vimont
5b8e9aa0e9 Move toUnsigned() to a Binary util class
PR #3369 <https://github.com/Genymobile/scrcpy/pull/3369>
2022-08-28 15:23:08 +02:00
Derek Wu
9c1722f428 Use DisplayManagerGlobal instance
Use the client instance to communicate with the DisplayManager server.

Fixes #3446 <https://github.com/Genymobile/scrcpy/issues/3446>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2022-08-19 18:03:38 +02:00
Romain Vimont
0fca2ad830 Add option to not power on on start
By default, on start, the device is powered on. To prevent this
behavior, add a new option --no-power-on.

Fixes #3148 <https://github.com/Genymobile/scrcpy/issues/3148>
PR #3210 <https://github.com/Genymobile/scrcpy/pull/3210>
2022-04-28 19:12:52 +02:00
Romain Vimont
6a4a4a283d Remove obsolete alternative injection method
The previous commit replaced the IInterface instance (the "input"
service) by the InputManager instance (retrieved by
InputManager.getInstance()).

Both define an "injectInputEvent" method, but the alternate version
(probably) does not concern the InputManager.

This reverts commit b7a06278fe.

PR #3190 <https://github.com/Genymobile/scrcpy/pull/3190>
2022-04-22 09:52:41 +02:00
Romain Vimont
7d8b72d4a6 Adapt event injection to Android 13
Using the "input" service results in a permission error in Android 13.

Use the InputManager instance (retrieved by InputManager.getInstance())
instead.

Fixes #3186 <https://github.com/Genymobile/scrcpy/issues/3186>
PR #3190 <https://github.com/Genymobile/scrcpy/pull/3190>
2022-04-22 09:52:41 +02:00
Romain Vimont
6a9b2f2c36 Remove spurious empty line 2022-02-22 18:31:37 +01:00
Romain Vimont
71b41d846f Also retry on IllegalArgumentException
MediaCodec.configure() may throw an IllegalArgumentException if it does
not support the requested size. Also retry on this exception.

Fixes #2993 <https://github.com/Genymobile/scrcpy/issues/2993>
Refs #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
Refs #2990 <https://github.com/Genymobile/scrcpy/pull/2990>
PR #3043 <https://github.com/Genymobile/scrcpy/pull/3043>
2022-02-22 10:27:11 +01:00
Romain Vimont
ccbe370cc5 Add --no-cleanup option
It might be useful not to cleanup on exit, for example to leave the
screen turned off, or keep the server binary on the device (via the
server option "cleanup=false").

Fixes #1764 <https://github.com/Genymobile/scrcpy/issues/1764>
PR #3020 <https://github.com/Genymobile/scrcpy/pull/3020>
2022-02-15 19:25:57 +01:00
Romain Vimont
67068e4e3d Pass key frame flag from the device
MediaCodec indicates when a packet is a key frame. Transmit it to the
client.
2022-02-11 21:32:55 +01:00
Romain Vimont
e3c2398aa2 Store packet flags in PTS most significant bits
A special PTS value was used to encode a config packet.

To prepare for adding more flags, use the most significant bits of the
PTS field to store flags.
2022-02-11 21:32:11 +01:00
Romain Vimont
c0a75ca746 Downscale and retry also on early MediaCodec error
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>
2022-02-02 08:22:17 +01:00
Romain Vimont
c8dc1917f4 Do not restore power mode if --no-control
This totally disables deferred cleanup when --no-control is passed.

Refs f289d206ea
2022-01-27 16:47:51 +01:00
Romain Vimont
2faf9715be Add server option raw_video_stream
For convenience, this new option forces the 3 following options:
 - send_device_meta=false
 - send_frame_meta=false
 - send_dummy_byte=false

This allows to send a raw H.264 stream on the video socket.

Concretely:

    adb push scrcpy-server /data/local/tmp/scrcpy-server.jar
    adb forward tcp:1234 localabstract:scrcpy
    adb shell CLASSPATH=/data/local/tmp/scrcpy-server.jar \
        app_process / com.genymobile.scrcpy.Server 1.21 \
        raw_video_stream=true tunnel_forward=true control=false

As soon as a client connects via TCP to localhost:1234, it will receive
the raw H.264 stream.

Refs #1419 comment <https://github.com/Genymobile/scrcpy/pull/1419#issuecomment-1013964650>
PR #2971 <https://github.com/Genymobile/scrcpy/pull/2971>
2022-01-27 16:47:51 +01:00
Romain Vimont
45a5e560df Add server option send_dummy_byte
If set to false, no dummy byte is written to detect a connection error.

PR #2971 <https://github.com/Genymobile/scrcpy/pull/2971>
2022-01-26 11:30:46 +01:00
Romain Vimont
3ba32c2a0d Add server option send_device_meta
Similar to send_device_frame, this option allows to disable sending the
device name and size on start.

This is only useful when using the scrcpy-server alone to get a raw
H.264 stream, without using the scrcpy client.

PR #2971 <https://github.com/Genymobile/scrcpy/pull/2971>
2022-01-26 11:30:37 +01:00
Romain Vimont
6b21f4ae13 Reorder scrcpy-server options
Move the options unused by the scrcpy client at the end.

These options may be useful to use scrcpy-server directly (to get a raw
H.264 stream for example).

PR #2971 <https://github.com/Genymobile/scrcpy/pull/2971>
2022-01-26 11:30:30 +01:00
Romain Vimont
31a5d0c2bf Move call to send device name and size
This will allow to optionally disable it.

PR #2971 <https://github.com/Genymobile/scrcpy/pull/2971>
2022-01-26 11:30:19 +01:00
Romain Vimont
a9429efa34 Fix downsize on error before first frame
Retry with a lower definition if MediaCodec fails before the first
frame, not the first packet.

In practice, the first packet is a config packet without any frame, and
MediaCodec might fail just after.

Refs 2eb6fe7d81
Refs #2963 <https://github.com/Genymobile/scrcpy/issues/2963>
2022-01-23 21:46:57 +01:00
Romain Vimont
262506c733 Limit retry-on-error to IllegalStateException
MediaCodec errors always trigger IllegalStateException or a subtype
(like MediaCodec.CodecException).

In practice, this avoids to retry if the error is caused by an
IOException when writing the video packet to the socket.
2022-01-21 21:52:29 +01:00
Romain Vimont
2eb6fe7d81 Downsize on error only before the first frame
The purpose of automatic downscaling on error is to make mirroring work
by just starting scrcpy without an explicit -m value, even if the
encoder could not encode at the screen definition.

It is only useful when we detect an encoding failure before the first
frame. Downsizing later could be surprising, so disable it.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2022-01-21 18:44:05 +01:00
Romain Vimont
0ec64baad4 Remove MediaCodec error suggestion fix
Now that scrcpy attempts with a lower definition on any MediaCodec
error (or the user explicitly requests to disable auto-downsizing), the
suggestion is unnecessary.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2022-01-21 18:41:26 +01:00
Romain Vimont
15bf27afdd Make auto-downsize on error optional
Add --no-downsize-on-error option to disable attempts to use a lower
definition on MediaCodec error.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2022-01-21 18:36:46 +01:00
Romain Vimont
26b4104844 Downsize on error
Some devices are not able to encode at the device screen definition.

Instead of just failing, try with a lower definition on any MediaCodec
error.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2022-01-21 18:36:46 +01:00
Romain Vimont
723faa5dee Remember Device parameters
This will allow to reuse them to recreate a ScreenInfo instance in order
to change the maxSize value on MediaCodec error.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2022-01-21 18:36:46 +01:00
Romain Vimont
162043911e Compute screen size without DisplayInfo instance
Use the actual rotation and size values directly.

This will allow to automatically change the maxSize value on MediaCodec
error.

PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
2022-01-21 18:36:46 +01:00
Romain Vimont
117fe32626 Fix visibility modifier
Refs b7a06278fe
2022-01-21 18:36:44 +01:00
Thomas Rebele
b7a06278fe Fix NoSuchMethodException for injectInputEvent()
Some devices with modified ROMs expose a different signature for
injectInputEvent().

Fixes #2250 <https://github.com/Genymobile/scrcpy/issues/2250>
PR #2946 <https://github.com/Genymobile/scrcpy/pull/2946>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2022-01-18 10:15:55 +01:00
Romain Vimont
60bf133ac2 Add final modifier to ScreenEncoder fields
These fields are only set from the constructor.
2022-01-15 23:25:55 +01:00
Romain Vimont
924375487e Pass buttons state in scroll events
A scroll event might be produced when a mouse button is pressed (for
example when scrolling while selecting a text). For consistency, pass
the actual buttons state (instead of 0).

In practice, it seems that this use case does not work properly with
Android event injection, but it will work with HID mouse.
2022-01-04 17:41:40 +01:00
Romain Vimont
cabcbc2b15 Do not create control socket if no control
If --no-control is enabled, then it is not necessary to create a second
communication socket between the client and the server.

This also facilitates the use of the server alone (without the client)
to receive only the raw video stream.
2021-12-08 23:41:38 +01:00
Romain Vimont
e2b3968c66 Always synchronize clipboard on explicit COPY/CUT
If --no-clipboard-autosync is enabled, the automatic clipboard
synchronization performed whenever the device clipboard changes is
disabled.

But on explicit COPY and CUT scrcpy shortcuts (MOD+c and MOD+x), the
clipboard should still be synchronized, so that it remains possible to
copy-paste from the device to the computer.

This is consistent with the behavior of MOD+v, which pastes the computer
clipboard to the device.

Refs #2228 <https://github.com/Genymobile/scrcpy/issues/2228>
Refs #2817 <https://github.com/Genymobile/scrcpy/pull/2817>
PR #2834 <https://github.com/Genymobile/scrcpy/pull/2834>
2021-11-29 22:00:55 +01:00
Romain Vimont
bfcb9d06c3 Expose sync mode for injecting events
Expose the inject input event mode so that it is possible to wait for
the events to be "finished". This will be necessary to read the
clipboard content only after the COPY or CUT key event is handled.

PR #2834 <https://github.com/Genymobile/scrcpy/pull/2834>
2021-11-29 22:00:21 +01:00
Romain Vimont
dc19ae334d Move acknowledgment handling
Handle all actions related to SET_CLIPBOARD from the dedicated method.

PR #2834 <https://github.com/Genymobile/scrcpy/pull/2834>
2021-11-29 21:58:30 +01:00
Romain Vimont
4c47598865 Make lockVideoOrientation option name uniform
On the server, the option was named lockedVideoOrientation.
2021-11-24 21:33:58 +01:00
Romain Vimont
04e5537f8c Pass server parameters as key=value pairs
The options values to configure the server were identified by their
command-line argument index. Now that there are a lot of arguments, many
of them being booleans, it became unreadable and error-prone.

Identify the arguments by a key string instead, and make them optional.

This will also simplify running the server manually for debugging.
2021-11-24 21:23:20 +01:00
Romain Vimont
2c3099e2de Parse codec options early
For consistency with other options, parse the codec options on the
server before storing them in the Options instance.
2021-11-24 21:06:02 +01:00
Romain Vimont
6abff46c9f Add option to disable clipboard autosync
By default, scrcpy automatically synchronizes the computer clipboard to
the device clipboard before injecting Ctrl+v, and the device clipboard
to the computer clipboard whenever it changes.

This new option --no-clipboard-autosync disables this automatic
synchronization.

Fixes #2228 <https://github.com/Genymobile/scrcpy/issues/2228>
PR #2817 <https://github.com/Genymobile/scrcpy/pull/2817>
2021-11-24 09:44:39 +01:00
Romain Vimont
41abe021e2 Make the device acknowledge device clipboard
If the client provided a sequence number on SET_CLIPBOARD request, make
the device send back an acknowledgement once the clipboard is set.

PR #2814 <https://github.com/Genymobile/scrcpy/pull/2814>
2021-11-23 21:15:05 +01:00
Romain Vimont
2a0730ee9b Add device clipboard set acknowledgement
Add a device message type so that the device could send acknowledgements
for SET_CLIPBOARD requests.

PR #2814 <https://github.com/Genymobile/scrcpy/pull/2814>
2021-11-23 21:15:05 +01:00
Romain Vimont
901d837165 Add sequence number to set_clipboard request
This will allow the client to request an acknowledgement.

PR #2814 <https://github.com/Genymobile/scrcpy/pull/2814>
2021-11-23 21:15:05 +01:00
Romain Vimont
ee93d2aac1 Configure init and cleanup asynchronously
Accessing the settings (like --show-touches) on start should not delay
screen mirroring.

PR #2802 <https://github.com/Genymobile/scrcpy/pull/2802>
2021-11-18 08:37:32 +01:00
Romain Vimont
c29a0bf675 Do not quit on cleanup configuration failure
Cleanup is used for some options like --show-touches to restore the
state on exit.

If the configuration fails, do not crash the whole process. Just log an
error.

PR #2802 <https://github.com/Genymobile/scrcpy/pull/2802>
2021-11-18 08:37:28 +01:00
Romain Vimont
411bb0d18e Move init and cleanup to a separate method
PR #2802 <https://github.com/Genymobile/scrcpy/pull/2802>
2021-11-18 08:37:26 +01:00
Romain Vimont
cc0902b13c Read/write settings via command on Android >= 12
Before Android 8, executing the "settings" command from a shell was
very slow (~1 second), because it spawned a new app_process to execute
Java code. Therefore, to access settings without performance issues,
scrcpy used private APIs to read from and write to settings.

However, since Android 12, this is not possible anymore, due to
permissions changes.

To make it work again, execute the "settings" command on Android 12 (or
on previous version if the other method failed). This method is faster
than before Android 8 (~100ms).

Fixes #2671 <https://github.com/Genymobile/scrcpy/issues/2671>
Fixes #2788 <https://github.com/Genymobile/scrcpy/issues/2788>
PR #2802 <https://github.com/Genymobile/scrcpy/pull/2802>
2021-11-18 08:37:22 +01:00
Romain Vimont
48b572c272 Add throwable parameter to Log.w()
When an exception occurs, we might want to log a warning instead of an
error.

PR #2802 <https://github.com/Genymobile/scrcpy/pull/2802>
2021-11-18 08:37:18 +01:00
Romain Vimont
94feae71f2 Report settings errors via Exceptions
Settings read/write errors were silently ignored. Report them via a
SettingsException so that the caller can handle them.

This allows to log a proper error message, and will also allow to
fallback to a different settings method in case of failure.

PR #2802 <https://github.com/Genymobile/scrcpy/pull/2802>
2021-11-18 08:37:02 +01:00
Romain Vimont
67170437f1 Wrap settings management into a Settings class
Until now, the code that needed to read/write the Android settings had
to explicitly open and close a ContentProvider.

Wrap these details into a Settings class.

This paves the way to provide an alternative implementation of settings
read/write for Android >= 12.

PR #2802 <https://github.com/Genymobile/scrcpy/pull/2802>
2021-11-18 08:36:48 +01:00
Romain Vimont
8df42cec82 Fix workarounds for Meizu
Workarounds.fillAppInfo() is necessary for Meizu devices even before the
first call to internalStreamScreen(), but it is harmful on other
devices (#940).

Therefore, simplify the workaround, by calling fillAppInfo() only if
Build.BRAND equals "meizu" (case insensitive).

Fixes #240 <https://github.com/Genymobile/scrcpy/issues/240> (again)
Fixes #2656 <https://github.com/Genymobile/scrcpy/issues/2656>
2021-09-22 15:33:17 +02:00
Romain Vimont
fa100b814b Add support for expandNotificationsPanel() variant
Some custom vendor ROM added an int as a parameter.

Fixes #2551 <https://github.com/Genymobile/scrcpy/issues/2551>
2021-09-11 10:46:25 +02:00
Romain Vimont
116acc8d25 Use SOURCE_MOUSE for scroll events
This has no practical impact (AFAIK), but a scroll events should come
from a mouse.

Refs #2602 <https://github.com/Genymobile/scrcpy/issues/2602>
2021-08-28 23:14:56 +02:00
Marti Raudsepp
937fa704a6 Add --verbosity=verbose log level
PR #2371 <https://github.com/Genymobile/scrcpy/pull/2371>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2021-06-20 12:34:19 +02:00
Romain Vimont
b846d3a085 Adapt call() on ContentProvider for Android 12
Android 12 changed one of the call() overloads with a new parameter
AttributionSource. Adapt the wrapper.

Fixes #2402 <https://github.com/Genymobile/scrcpy/issues/2402>
2021-06-19 22:59:48 +02:00
Romain Vimont
16a63e0917 Use non-secure display for Android 12 preview
Android 12 preview identifies as Android 11, but its codename is "S".

Refs #2129 <https://github.com/Genymobile/scrcpy/issues/2129>
2021-06-11 10:02:52 +02:00
Romain Vimont
f7533e8896 Use non-secure display for Android >= 12
Since Android 12, secure displays could not be created with shell
permissions anymore.

Refs commit 1fdde490fd
Fixes #2129 <https://github.com/Genymobile/scrcpy/issues/2129>
2021-06-11 09:37:29 +02:00
Romain Vimont
969bfd4374 Serialize clean-up configuration
This avoids to pass each option as individual parameter and parse them
manually (it's still "manual" in the Parcelable implementation).

Refs #824 <https://github.com/Genymobile/scrcpy/pull/824#issuecomment-780319422>

Reviewed-by: Yu-Chen Lin <npes87184@gmail.com>
2021-06-11 09:33:29 +02:00
Romain Vimont
233f8e6cc4 Rename keycode injection method
Make it explicit that it injects both "press" and "release" events.
2021-04-30 23:07:37 +02:00
Romain Vimont
9a7d351d67 Simplify non-static injectEvent() implementation
Just call the static version (having a displayId) from the non-static
version (using the displayId field).
2021-04-30 23:07:37 +02:00