Commit Graph

551 Commits (master)

Author SHA1 Message Date
Romain Vimont 751a3653a0 Add missing @Override annotations
PR #3978 <https://github.com/Genymobile/scrcpy/pull/3978>
1 year ago
Romain Vimont 9c08eb79cb Close connection at the end of finally-block
The async processors use the socket file descriptors from the
connection. Therefore, the connection must not be closed before all
async processor threads are joined.

PR #3978 <https://github.com/Genymobile/scrcpy/pull/3978>
1 year ago
Romain Vimont 9cfea347d0 Remove Options setters
Now that options parsing is performed from the Options class, setters
are not necessary anymore.
1 year ago
Romain Vimont ce064fb5e0 Move options parsing to Options class 1 year ago
Romain Vimont afcdfc7fd7 Fix checkstyle violation
Checkstyle reported this error:

    [ant:checkstyle] [ERROR] AudioCapture.java:89:145: '+' should be on
    a new line. [OperatorWrap]
1 year ago
Simon Chan fdf465851c Add Android version check in raw audio recorder
Do not attempt to capture audio below Android 11, this may cause a
segfault on the device.

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
1 year ago
Romain Vimont f77e1c474e Fix copy-paste for some devices
On Honor Magic 5 Pro, the method to get the clipboard content has been
modified in the framework.

Adapt the call to make it work also on this device.

Fixes #3885 <https://github.com/Genymobile/scrcpy/issues/3885>
1 year ago
Romain Vimont 2fff9b9edf Adapt FakeContext for Android 14
This fixes audio for Android 14 developer preview 2.

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

Suggested-by: Namelesswonder <Namelesswonder@users.noreply.github.com>
1 year ago
Romain Vimont 57f879d68a Adapt clipboard wrappers to Android 14
A new deviceId parameter has been added.

Fixes #3784 <https://github.com/Genymobile/scrcpy/issues/3784>
1 year ago
Romain Vimont 3626d90004 Use separate audio capture code for Android 11
The code to start audio capture is more complicated for Android 11
(launch a fake popup, wait, make several attempts, close the shell
package).

Use a distinct code path specific to Android 11.
1 year ago
Romain Vimont 02f4ff7534 Make 3 attempts to start AudioRecord
On Android 11, a fake popup must be briefly opened to make the system
think that the shell app is in the foreground so that audio may be
recorded.

Making the shell app foreground may take some time depending on the
device, so make 3 attempts, waiting 100ms before each.

Fixes #3796 <https://github.com/Genymobile/scrcpy/issues/3796>
1 year ago
Romain Vimont a3871130cc List available encoders on failure
When the creation of an encoder fails, log an explicit error message
with the list of available encoders.
1 year ago
Romain Vimont d7841664f4 Simplify logic in setScreenPowerMode()
Refs <f2dee20a20 (r104417398)>

Suggested-by: brunoais <brunoaiss@gmail.com>
1 year ago
Romain Vimont 6ba99a62ff Split workarounds to fix audio on some devices
There were several workarounds applied in a single method. Some of them
are specific to Meizu phones, but cause issues on other devices.

Split the method to be able to only fill the app context for audio
capture without applying the Meizu workarounds.

Fixes #3801 <https://github.com/Genymobile/scrcpy/issues/3801>
1 year ago
Romain Vimont 337d6c2fd3 Fail on empty AudioRecord read()
If read() returns 0, then there is no data. According to the
documentation, it happens if the buffer is not a direct buffer:
<https://developer.android.com/reference/android/media/AudioRecord#read(java.nio.ByteBuffer,%20int)>

Refs #3812 <https://github.com/Genymobile/scrcpy/issues/3812>
1 year ago
Romain Vimont f1b2d6bbbb Bump version to 2.0 1 year ago
Romain Vimont 2380879376 Remove unused IOException
IOException may not be thrown from this method.
1 year ago
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.
1 year ago
Romain Vimont aa1efbc35c Rename sendCodecId to sendCodecMeta
This will allow the codec header to contain more than the codec id.
1 year ago
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
1 year ago
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.
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
Romain Vimont a205ff6c8b Log display sizes in display list
This is more convenient than just the display id alone.
1 year ago
Romain Vimont b65301f672 Add --list-displays
Add an option to list the device displays properly.
1 year ago
Romain Vimont 2596ca02f0 Move log message helpers to LogUtils
This class will also contain other log helpers.
1 year ago
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>
1 year ago
Romain Vimont 9196dc1563 Add --list-encoders
Add an option to list the device encoders properly.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
1 year ago
Romain Vimont f9960e959f Add --audio-encoder
Similar to --video-encoder, but for audio.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
1 year ago
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>
1 year ago
Romain Vimont b03c864c70 Add --audio-codec-options
Similar to --video-codec-options, but for audio.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
1 year ago
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>
1 year ago
Romain Vimont 4601735e51 Add support for AAC audio codec
Add option --audio-codec=aac.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
Romain Vimont e694619d53 Rename --encoder to --video-encoder
This prepares the introduction of --audio-encoder.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
1 year ago
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>
1 year ago
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>
1 year ago
Romain Vimont cee40ca047 Rename --codec to --video-codec
This prepares the introduction of --audio-codec.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
Romain Vimont 464a35b05e Make streamer more generic
Expose a method to write a packet from raw metadata (without
BufferInfo).
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
Romain Vimont 84ba6435bb Use shell package name for workarounds
For consistency.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
1 year ago
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>
1 year ago
Romain Vimont 820189b6a6 Use PACKAGE_NAME from FakeContext
Remove duplicated constant.

PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
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.
1 year ago
Romain Vimont ae9b08b905 Move screen encoder initialization
This prepares further refactors.
1 year ago
Romain Vimont 51628201b7 Write streamer header from ScreenEncoder
The screen encoder is responsible for writing data to the video
streamer.
1 year ago
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
1 year ago
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).
1 year ago
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.
1 year ago
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.
1 year ago
Romain Vimont 5bf52a98ed Remove manifest package name
As reported by gradle:

> Setting the namespace via a source AndroidManifest.xml's package
> attribute is deprecated.
>
> Please instead set the namespace (or testNamespace) in the module's
> build.gradle file, as described here:
> https://developer.android.com/studio/build/configure-app-module#set-namespace
1 year ago
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.
1 year ago
Romain Vimont d5dff239c8 Suggest commands with an explicit '=' 1 year ago
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
1 year ago
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.
1 year ago
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
1 year ago
Romain Vimont 45b2e6db5c Log component stopped in finally clause
The message must be logged even when no exception occurs.
1 year ago
Romain Vimont 400a1c69b1 Join all threads before end of main
Some calls from separate threads may throw exceptions once the main()
method has returned.
1 year ago
Romain Vimont 6524e90c68 Remove unused constant
This line was committed by error.

Refs 3e517cd40e
1 year ago
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>
1 year ago
Romain Vimont d2dce51038 Add support for AV1
Add option --codec=av1.

PR #3713 <https://github.com/Genymobile/scrcpy/pull/3713>
1 year ago
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>
1 year ago
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>
1 year ago
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.
1 year ago
Romain Vimont 3aac74e9e9 Move variable assignment
Computing eof flag is not necessary if rotation changed.
1 year ago
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.
1 year ago
Romain Vimont 36d656e91f Improve workarounds call comments 1 year ago
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>
1 year ago
Romain Vimont 4177de5880 Do not expose controller threads
The way the controller executes its events asynchronously is an
implementation detail.
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
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>
1 year ago
Romain Vimont a52053421a Extract retry handling
Move the code to downscale and retry on error out of the catch-block.

Refs 26b4104844
1 year ago
Romain Vimont a9b2697f3e Move local variables declarations
This makes it clear that these local variables are only passed to
setDisplaySurface().
1 year ago
Romain Vimont b53d2c66e0 Remove useless setSize() method
Inline its content. It makes the logic of internalStreamScreen() more
readable (it reduces the number of indirections).
1 year ago
Romain Vimont 6cccf3ab2a Remove useless configure() method
Inline its single call.
1 year ago
Romain Vimont 52f85fd6f1 Keep the same MediaCodec instance across sessions
Calling codec.reset() is sufficient.
1 year ago
Romain Vimont 91c69ad95c Remove useless destroyDisplay() method
The method made exactly one simple call. Just make the call directly.
1 year ago
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).
1 year ago
Romain Vimont 74d32e612d Terminate loop explicitly on interrupted
Make explicit that the loop terminates when the current thread is
interrupted.
1 year ago
Romain Vimont bdba554118 Use Java lambdas where possible 1 year ago
Romain Vimont 234ad7ee78 Support Java lambdas in build_without_gradle.sh
Building Java source code using lambdas requires core-lambda-stubs.jar.

Refs #3657 <https://github.com/Genymobile/scrcpy/issues/3657>
1 year ago
Romain Vimont 8cbbcc939f Add missing final modifiers 1 year ago
Romain Vimont b22810b17c Use try-with-resources
Replace an explicit try-finally by a try-with-resources block.
1 year ago
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").
1 year ago
Romain Vimont e6cd42355b Use separate gen dir to build without gradle
The generated source files were written to the classes dir. Use a
separate gen dir instead.
1 year ago
Romain Vimont fe21158c20 Bump version to 1.25 1 year ago
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>
1 year ago
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>
1 year ago
Romain Vimont b51841e85d Upgrade junit to 4.13.2 1 year ago
Romain Vimont 6469b55861 Fix CommandParserTest code style
Make checkstyle happy.
2 years ago
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>
2 years ago
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).
2 years ago
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>
2 years ago
Romain Vimont 4a5cdcd390 Extract $BUILD_TOOLS_DIR
In the script to build without gradle, the build-tools full path is used
at several places. Use a separate variable for readability.
2 years ago
Romain Vimont 0a0a446ea6 Upgrade Android SDK to 33 2 years ago
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>
2 years ago
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>
2 years ago
Romain Vimont 136ab8c199 Add unit test for float decoding
PR #3369 <https://github.com/Genymobile/scrcpy/pull/3369>
2 years ago
Romain Vimont 3848ce86f1 Extract conversion from u16 fixed-point to float
PR #3369 <https://github.com/Genymobile/scrcpy/pull/3369>
2 years ago
Romain Vimont 5b8e9aa0e9 Move toUnsigned() to a Binary util class
PR #3369 <https://github.com/Genymobile/scrcpy/pull/3369>
2 years ago
Romain Vimont 3a66b5fd01 Remove deprecated meson.source_root()
This method is deprecated since Meson 0.56.0:
<https://mesonbuild.com/Release-notes-for-0-56-0.html#mesonbuild_root-and-mesonsource_root-are-deprecated>

We could replace it with meson.project_source_root(), but this would
make Meson 0.56 or above mandatory. Since the path in always computed
from the server/ directory, just add '..' to reference the root project
directory.

Refs c456e38264
2 years ago
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>
2 years ago
Romain Vimont 7f2f5950f2 Remove useless dependencies reference
There is no libs/ directory with local jar files.
2 years ago
Romain Vimont ef13d394fd Bump version to 1.24 2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
Romain Vimont 7deccef1c2 Bump version to 1.23 2 years ago
Romain Vimont 6a9b2f2c36 Remove spurious empty line 2 years ago
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>
2 years ago
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>
2 years ago
Romain Vimont 67068e4e3d Pass key frame flag from the device
MediaCodec indicates when a packet is a key frame. Transmit it to the
client.
2 years ago
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.
2 years ago
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>
2 years ago
Romain Vimont 64a09513ae Bump version to 1.22 2 years ago
Romain Vimont c8dc1917f4 Do not restore power mode if --no-control
This totally disables deferred cleanup when --no-control is passed.

Refs f289d206ea
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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.
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
Romain Vimont 117fe32626 Fix visibility modifier
Refs b7a06278fe
2 years ago
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>
2 years ago