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").
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>
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).
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>
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.
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>
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>
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>
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>
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>
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.
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>
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>
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>
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.
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.
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>
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.
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>
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>
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>
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>
Make the versionCode a decimal representation of the scrcpy version.
This will for example allow to correctly number the versionCode of
v1.17.1 after a v1.18 is released:
- v1.18 -> 11800
- v1.17.1 -> 11701
- v1.18.1 -> 11801