Commit Graph

64 Commits (87da68ee0d74831a2b44230c573a3b315c8fd7d3)

Author SHA1 Message Date
Simon Chan 87da68ee0d Handle UHID output
Use UHID output reports to synchronize CapsLock and VerrNum states.

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

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
3 months ago
Romain Vimont 021c5d371a Refactor DeviceMessageSender
Refactor DeviceMessage as a queue of message. This will allow to add
other message types.

PR #4473 <https://github.com/Genymobile/scrcpy/pull/4473>
3 months ago
Simon Chan 840680f546 Add UHID keyboard support
Use the following command:

    scrcpy --keyboard=uhid

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

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
3 months ago
Romain Vimont 4d5b67cc80 Log controller handling errors
On close, the controller is expected to throw an IOException because the
socket is closed, so the exception was ignored.

However, message handling actions may also throw IOException, and they
must not be silently ignored.

PR #4473 <https://github.com/Genymobile/scrcpy/pull/4473>
3 months ago
eiyooooo d894e270a7 Add rotation support for non-default display
Use new methods introduced by this commit:
<90c9005e68%5E%21/>

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
3 months ago
Romain Vimont 25f1e703b7 Extract ControlChannel class
This prevents many components from depending on the whole
DesktopConnection.
3 months ago
Romain Vimont 9efa162949 Configure clean up actions dynamically
Some actions may be performed when scrcpy exits, currently:
 - disable "show touches"
 - restore "stay on while plugged in"
 - power off screen
 - restore "power mode" (to disable "turn screen off")

They are performed from a separate process so that they can be executed
even when scrcpy-server is killed (e.g. if the device is unplugged).

The clean up actions to perform were configured when scrcpy started.
Given that there is no method to read the current "power mode" in
Android, and that "turn screen off" can be applied at any time using an
scrcpy shortcut, there was no way to determine if "power mode" had to be
restored on exit. Therefore, it was always restored to "normal", even
when not necessary.

However, setting the "power mode" is quite fragile on some devices, and
may cause some issues, so it is preferable to call it only when
necessary (when "turn screen off" has actually been called).

For that purpose, make the scrcpy-server main process and the clean up
process communicate the actions to perform over a pipe (stdin/stdout),
so that they can be changed dynamically. In particular, when the power
mode is changed at runtime, notify the clean up process.

Refs 1beec99f82
Refs #4456 <https://github.com/Genymobile/scrcpy/issues/4456>
Refs #4624 <https://github.com/Genymobile/scrcpy/issues/4624>
PR #4649 <https://github.com/Genymobile/scrcpy/pull/4649>
4 months ago
Romain Vimont c573bd2a33 Fix java code style 6 months ago
Romain Vimont fdbc9397a7 Name Java threads
Give a user-friendly name to Java threads created by the server.
12 months ago
Romain Vimont feab87053a Convert screen encoder to async processor
Contrary to the other tasks (controller and audio capture/encoding), the
screen encoder was executed synchronously. As a consequence,
scrcpy-server could not terminate until the screen encoder returned.

Convert it to an async processor. This allows to terminate on controller
error, and this paves the way to disable video mirroring.

PR #3978 <https://github.com/Genymobile/scrcpy/pull/3978>
1 year ago
Romain Vimont 751a3653a0 Add missing @Override annotations
PR #3978 <https://github.com/Genymobile/scrcpy/pull/3978>
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 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 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
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
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
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 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 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.
2 years ago
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>
3 years ago
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>
3 years ago
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>
3 years ago
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>
3 years ago
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>
3 years ago
Romain Vimont 233f8e6cc4 Rename keycode injection method
Make it explicit that it injects both "press" and "release" events.
3 years ago
brunoais 50eecdab28 Add control message to expand settings panel
PR #2260 <https://github.com/Genymobile/scrcpy/pull/2260>

Signed-off-by: Romain Vimont <rom@rom1v.com>
3 years ago
brunoais 66c581851f Rename control message type to COLLAPSE_PANELS
The collapsing action collapses any panels.

By the way, the Android method is named collapsePanels().

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
3 years ago
Romain Vimont d0739911a3 Forward DOWN and UP separately for right-click
The shortcut "back on screen on" is a bit special: the control is
requested by the client, but the actual event injection (POWER or BACK)
is determined on the device.

To properly inject DOWN and UP events for BACK, transmit the action as
a control parameter.

If the screen is off:
 - on DOWN, inject POWER (DOWN and UP) (wake up the device immediately)
 - on UP, do nothing
If the screen is on:
 - on DOWN, inject BACK DOWN
 - on UP, inject BACK UP

A corner case is when the screen turns off between the DOWN and UP
event. In that case, a BACK UP event will be injected, so it's harmless.

As a consequence of this change, the BACK button is now handled by
Android on mouse released. This is consistent with the keyboard shortcut
(Mod+b) behavior.

PR #2259 <https://github.com/Genymobile/scrcpy/pull/2259>
Refs #2258 <https://github.com/Genymobile/scrcpy/pull/2258>
3 years ago
Romain Vimont 0308ef43f2 Do not set buttons on touch events
BUTTON_PRIMARY must not be set for touch events:

> This button constant is not set in response to simple touches with a
> finger or stylus tip. The user must actually push a button.

<https://developer.android.com/reference/android/view/MotionEvent#BUTTON_PRIMARY>

Fixes #2169 <https://github.com/Genymobile/scrcpy/issues/2169>
3 years ago
Romain Vimont 40febf4a91 Use device id 0 for touch/mouse events
Virtual device is only for keyboard sources, not mouse or touchscreen
sources. Here is the value of InputDevice.getDevice(-1).toString():

    Input Device -1: Virtual
      Descriptor: ...
      Generation: 2
      Location: built-in
      Keyboard Type: alphabetic
      Has Vibrator: false
      Has mic: false
      Sources: 0x301 ( keyboard dpad )

InputDevice.getDeviceId() documentation says:

> An id of zero indicates that the event didn't come from a physical
> device and maps to the default keymap.

<https://developer.android.com/reference/android/view/InputEvent#getDeviceId()>

However, injecting events with a device id of 0 causes event.getDevice()
to be null on the client-side.

Commit 26529d377f used -1 as a workaround
to avoid a NPE on a specific Android TV device. But this is a bug in the
device system, which wrongly assumes that input device may not be null.

A similar issue was present in Flutter, but it is now fixed:
 - <https://github.com/flutter/flutter/issues/30665>
 - <https://github.com/flutter/engine/pull/7986>

On the other hand, using an id of -1 for touchscreen events (which is
invalid) causes issues for some apps:
<https://github.com/Genymobile/scrcpy/issues/2125#issuecomment-790535792>

Therefore, use a device id of 0.

An alternative could be to find an existing device matching the source,
like "adb shell input" does. See getInputDeviceId():
<https://android.googlesource.com/platform/frameworks/base.git/+/master/cmds/input/src/com/android/commands/input/Input.java>

But it seems better to indicate that the event didn't come from a
physical device, and it would not solve #962 anyway, because an Android
TV has no touchscreen.

Refs #962 <https://github.com/Genymobile/scrcpy/issues/962>
Fixes #2125 <https://github.com/Genymobile/scrcpy/issues/2125>
3 years ago
Romain Vimont 218636dc10 Inject touch events with smallest detectable size
A value of 1 means the "largest detectable size", a value of 0 means the
"smallest detectable size".

https://developer.android.com/reference/android/view/MotionEvent.PointerCoords#size
https://developer.android.com/reference/android/view/MotionEvent#AXIS_SIZE

Fixes #2125 <https://github.com/Genymobile/scrcpy/issues/2125>
3 years ago
Romain Vimont adc547fa6e Add an option to forward all clicks
Add --forward-all-clicks to disable mouse shortcuts and forward middle
and right clicks to the device instead.

Fixes #1302 <https://github.com/Genymobile/scrcpy/issues/1302>
Fixes #1613 <https://github.com/Genymobile/scrcpy/issues/1613>
4 years ago
Romain Vimont 0c5e0a4f6d Make Device methods static when possible
The behavior of some methods do not depend on the user-provided options.
These methods can be static. This will allow to call them directly from
the cleanup process.
4 years ago
Romain Vimont 38940ffe89 Revert "Inject WAKEUP instead of POWER"
WAKEUP does not work on some devices.

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

This reverts commit 322f1512ea.
4 years ago
brunoais cf9d44979c Keep the screen off on powering on
PR #1577 <https://github.com/Genymobile/scrcpy/pull/1577>
Fixes #1573 <https://github.com/Genymobile/scrcpy/issues/1573>

Signed-off-by: Romain Vimont <rom@rom1v.com>
4 years ago
Romain Vimont eabaf6f7bd Simplify PASTE option for "set clipboard"
When the client requests to set the clipboard, it may request to press
the PASTE key in addition. To be a bit generic, it was stored as a flag
in ControlMessage.java.

But flags suggest that it represents a bitwise union. Use a simple
boolean instead.
4 years ago
Romain Vimont 322f1512ea Inject WAKEUP instead of POWER
To power the device on, inject KEYCODE_WAKEUP to avoid a possible
race condition (the device might become off between the test
isScreenOn() and the POWER keycode injection).
4 years ago
Romain Vimont a973757fd1 Warn on ignored touch event
In theory, this was expected to only happen when a touch event is sent
just before the device is rotated, but some devices do not respect the
encoding size, causing an unexpected mismatch.

Refs #1518 <https://github.com/Genymobile/scrcpy/issues/1518>
4 years ago
Romain Vimont 334964c380 Make setScreenPowerMode() method static
Its implementation does not use the instance at all.
4 years ago
xeropresence 3c1ed5d86c Handle repeating keycodes
Initialize "repeat" count on key events.

PR #1519 <https://github.com/Genymobile/scrcpy/pull/1519>
Refs #1013 <https://github.com/Genymobile/scrcpy/pull/1013>

Signed-off-by: Romain Vimont <rom@rom1v.com>
4 years ago
Romain Vimont 93a5c5149d Push clipboard text only if not null
In practice, it does not change anything (it just avoids a spurious
wake-up), but semantically, it makes no sense to call
pushClipboardText() with a null value.
4 years ago
Romain Vimont fc1dec0270 Paste on "set clipboard" if possible
Ctrl+Shift+v synchronizes the computer clipboard to the Android device
clipboard. This feature had been added to provide a way to copy UTF-8
text from the computer to the device.

To make such a paste more straightforward, if the device runs at least
Android 7, also send a PASTE keycode to paste immediately.

<https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_PASTE>

Fixes #786 <https://github.com/Genymobile/scrcpy/issues/786>
4 years ago
Romain Vimont 4bbabfb4ef Move injection methods to Device
Only the main injection method was exposed on Device, the convenience
methods were implemented in Controller.

For consistency, move them all to the Device class.
4 years ago
Romain Vimont c7a33fac36 Log actions on the caller side
Some actions are exposed by the Device class, but logging success should
be done by the caller.
4 years ago
Romain Vimont e2d5f0e7fc Send scroll events as a touchscreen
Scroll events were sent with a mouse input device. When scrolling on a
list, this could cause the whole list to be focused, and drawn with the
focus color as background.

Send scroll events with a touchscreen input device instead (like motion
events).

Fixes #1362 <https://github.com/Genymobile/scrcpy/issues/1362>
4 years ago
e_vigurskiy 4150eedcdf Add display id parameter
Add --display command line parameter to specify a display id.

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

Signed-off-by: Romain Vimont <rom@rom1v.com>
4 years ago