The keyboard settings can be opened by:
adb shell am start -a android.settings.HARD_KEYBOARD_SETTINGS
Add a shortcut (MOD+k) for convenience if the current keyboard is HID.
Use UHID output reports to synchronize CapsLock and VerrNum states.
Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
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.
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>
This exception is a super-type of:
- ClassNotFoundException
- IllegalAccessException
- InstantiationException
- InvocationTargetException
- NoSuchFieldException
- NoSuchMethodException
Use it to simplify.
Create the service managers from each manager wrapper class rather than
from their getter in ServiceManager.
The way a wrapper retrieve the underlying service is an implementation
detail, and it must be consistent with the way it accesses it, so it is
better to write the creation in the wrapper.
If the initial timestamp could not be retrieved, use the current time as
returned by System.nanoTime(). In practice, it is the same time base as
AudioRecord timestamps.
Fixes#4536 <https://github.com/Genymobile/scrcpy/issues/4536>
The result is assigned to a long (64-bit signed integer), but the
intermediate multiplication was stored in an int (32-bit signed
integer).
This value is only used as a fallback when no timestamp could be
retrieved, that's why it did not cause too much harm so far.
Fixes#4536 <https://github.com/Genymobile/scrcpy/issues/4536>
Reported by checkstyle:
> [ant:checkstyle] [INFO]
> scrcpy/server/src/main/java/com/genymobile/scrcpy/wrappers/ClipboardManager.java:48:
> Line is longer than 150 characters (found 167). [LineLength]
On some Samsung devices, DisplayManagerGlobal.getDisplayInfoLocked()
calls ActivityThread.currentActivityThread().getConfiguration(), which
requires a non-null ConfigurationController.
Fixes <https://github.com/Genymobile/scrcpy/issues/4467>
On Android 14 (Pixel 8), a device rotation while the camera app was
running resulted in an incorrect capture.
Destroying and recreating the display fixes the issue.
If the difference of PTS between two consecutive blocks of audio is less
than 1 sample, then it will be considered as non-increasing by FFmpeg
muxers having a time_base of 1/sample_rate.
Increase the PTS by 1 sample instead.
If several reads are performed for a single captured audio block (e.g.
if the read size is smaller than the captured block), then the provided
timestamp was the same for all packets.
Recompute the timestamp for each of them.
In practice, the system captures audio samples by blocks of 1024
samples.
Remplace the hardcoded value of 5 milliseconds (240 samples), and let
AudioRecord fill the input buffer provided by MediaCodec (or by
AudioRawRecorder), with a maximum size of 1024 samples (just in case).
It is incorret to ever call:
streamer.writeDisableStream(...);
after:
streamer.writeAudioHeader();
Move the try-catch block so that it can never happen.
Some devices may provide invalid ranges, causing an
IllegalArgumentException "lower must be less than or equal to upper".
Catch the exception to list the cameras anyway.
Refs #4403 <https://github.com/Genymobile/scrcpy/issues/4403>
Interrupting async processors may require to shutdown the connection to
wake up blocking calls.
Therefore, shutdown the connection first, then join the threads, then
close the connection.
Refs commit 9c08eb79cb