diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5875c6bf..a77b7ff1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -74,7 +74,6 @@ jobs: - name: Install dependencies run: | - sudo apt update sudo apt install -y meson ninja-build nasm ffmpeg libsdl2-2.0-0 \ libsdl2-dev libavcodec-dev libavdevice-dev libavformat-dev \ libavutil-dev libswresample-dev libusb-1.0-0 libusb-1.0-0-dev \ @@ -84,7 +83,7 @@ jobs: run: release/test_client.sh build-linux-x86_64: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Check architecture run: | @@ -100,7 +99,6 @@ jobs: - name: Install dependencies run: | - sudo apt update sudo apt install -y meson ninja-build nasm ffmpeg libsdl2-2.0-0 \ libsdl2-dev libavcodec-dev libavdevice-dev libavformat-dev \ libavutil-dev libswresample-dev libusb-1.0-0 libusb-1.0-0-dev \ @@ -131,12 +129,14 @@ jobs: - name: Install dependencies run: | - sudo apt update sudo apt install -y meson ninja-build nasm ffmpeg libsdl2-2.0-0 \ libsdl2-dev libavcodec-dev libavdevice-dev libavformat-dev \ libavutil-dev libswresample-dev libusb-1.0-0 libusb-1.0-0-dev \ mingw-w64 mingw-w64-tools libz-mingw-w64-dev + - name: Workaround for old meson version run by Github Actions + run: sed -i 's/^pkg-config/pkgconfig/' cross_win32.txt + - name: Build run: release/build_windows.sh 32 @@ -162,12 +162,14 @@ jobs: - name: Install dependencies run: | - sudo apt update sudo apt install -y meson ninja-build nasm ffmpeg libsdl2-2.0-0 \ libsdl2-dev libavcodec-dev libavdevice-dev libavformat-dev \ libavutil-dev libswresample-dev libusb-1.0-0 libusb-1.0-0-dev \ mingw-w64 mingw-w64-tools libz-mingw-w64-dev + - name: Workaround for old meson version run by Github Actions + run: sed -i 's/^pkg-config/pkgconfig/' cross_win64.txt + - name: Build run: release/build_windows.sh 64 @@ -206,13 +208,6 @@ jobs: libtool - name: Build - env: - # the default Xcode (and macOS SDK) version can be found at - # - # - # then the minimal supported deployment target of that macOS SDK can be found at - # - MACOSX_DEPLOYMENT_TARGET: 10.13 run: release/build_macos.sh aarch64 # upload-artifact does not preserve permissions @@ -249,13 +244,6 @@ jobs: # autoconf and libtool are already installed on macos-13 - name: Build - env: - # the default Xcode (and macOS SDK) version can be found at - # - # - # then the minimal supported deployment target of that macOS SDK can be found at - # - MACOSX_DEPLOYMENT_TARGET: 10.13 run: release/build_macos.sh x86_64 # upload-artifact does not preserve permissions diff --git a/FAQ.md b/FAQ.md index 24722c74..5f089cd7 100644 --- a/FAQ.md +++ b/FAQ.md @@ -166,13 +166,14 @@ Rebooting the device is necessary once this option is set. ### Special characters do not work -The default text injection method is limited to ASCII characters. A trick allows -to also inject some [accented characters][accented-characters], +The default text injection method is [limited to ASCII characters][text-input]. +A trick allows to also inject some [accented characters][accented-characters], but that's all. See [#37]. To avoid the problem, [change the keyboard mode to simulate a physical keyboard][hid]. +[text-input]: https://github.com/Genymobile/scrcpy/issues?q=is%3Aopen+is%3Aissue+label%3Aunicode [accented-characters]: https://blog.rom1v.com/2018/03/introducing-scrcpy/#handle-accented-characters [#37]: https://github.com/Genymobile/scrcpy/issues/37 [hid]: doc/keyboard.md#physical-keyboard-simulation diff --git a/LICENSE b/LICENSE index 1196b3da..d9326a74 100644 --- a/LICENSE +++ b/LICENSE @@ -188,7 +188,7 @@ identification within third-party archives. Copyright (C) 2018 Genymobile - Copyright (C) 2018-2025 Romain Vimont + Copyright (C) 2018-2024 Romain Vimont Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index c1fd9f7f..09fa12b4 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@ source for the project. Do not download releases from random websites, even if their name contains `scrcpy`.** -# scrcpy (v3.2) +# scrcpy (v3.1) scrcpy _pronounced "**scr**een **c**o**py**"_ -This application mirrors Android devices (video and audio) connected via USB or -[TCP/IP](doc/connection.md#tcpip-wireless) and allows control using the -computer's keyboard and mouse. It does not require _root_ access or an app -installed on the device. It works on _Linux_, _Windows_, and _macOS_. +This application mirrors Android devices (video and audio) connected via +USB or [over TCP/IP](doc/connection.md#tcpip-wireless), and allows to control the +device with the keyboard and the mouse of the computer. It does not require any +_root_ access. It works on _Linux_, _Windows_ and _macOS_. ![screenshot](assets/screenshot-debian-600.jpg) @@ -78,16 +78,6 @@ Note that USB debugging is not required to run scrcpy in [OTG mode](doc/otg.md). - [macOS](doc/macos.md) -## Must-know tips - - - [Reducing resolution](doc/video.md#size) may greatly improve performance - (`scrcpy -m1024`) - - [_Right-click_](doc/mouse.md#mouse-bindings) triggers `BACK` - - [_Middle-click_](doc/mouse.md#mouse-bindings) triggers `HOME` - - Alt+f toggles [fullscreen](doc/window.md#fullscreen) - - There are many other [shortcuts](doc/shortcuts.md) - - ## Usage examples There are a lot of options, [documented](#user-documentation) in separate pages. @@ -207,10 +197,10 @@ work][donate]: [donate]: https://blog.rom1v.com/about/#support-my-open-source-work -## License +## Licence Copyright (C) 2018 Genymobile - Copyright (C) 2018-2025 Romain Vimont + Copyright (C) 2018-2024 Romain Vimont Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/app/data/bash-completion/scrcpy b/app/data/bash-completion/scrcpy index 9918918c..29130892 100644 --- a/app/data/bash-completion/scrcpy +++ b/app/data/bash-completion/scrcpy @@ -23,7 +23,6 @@ _scrcpy() { -d --select-usb --disable-screensaver --display-id= - --display-ime-policy= --display-orientation= -e --select-tcpip -f --fullscreen @@ -122,7 +121,7 @@ _scrcpy() { return ;; --audio-source) - COMPREPLY=($(compgen -W 'output playback mic mic-unprocessed mic-camcorder mic-voice-recognition mic-voice-communication voice-call voice-call-uplink voice-call-downlink voice-performance' -- "$cur")) + COMPREPLY=($(compgen -W 'output mic playback' -- "$cur")) return ;; --camera-facing) @@ -149,10 +148,6 @@ _scrcpy() { COMPREPLY=($(compgen -W '0 90 180 270 flip0 flip90 flip180 flip270' -- "$cur")) return ;; - --display-ime-policy) - COMPREPLY=($(compgen -W 'local fallback hide' -- "$cur")) - return - ;; --record-orientation) COMPREPLY=($(compgen -W '0 90 180 270' -- "$cur")) return diff --git a/app/data/zsh-completion/_scrcpy b/app/data/zsh-completion/_scrcpy index 450fc8f5..0897b9cc 100644 --- a/app/data/zsh-completion/_scrcpy +++ b/app/data/zsh-completion/_scrcpy @@ -16,7 +16,7 @@ arguments=( '--audio-codec-options=[Set a list of comma-separated key\:type=value options for the device audio encoder]' '--audio-dup=[Duplicate audio]' '--audio-encoder=[Use a specific MediaCodec audio encoder]' - '--audio-source=[Select the audio source]:source:(output playback mic mic-unprocessed mic-camcorder mic-voice-recognition mic-voice-communication voice-call voice-call-uplink voice-call-downlink voice-performance)' + '--audio-source=[Select the audio source]:source:(output mic playback)' '--audio-output-buffer=[Configure the size of the SDL audio output buffer (in milliseconds)]' {-b,--video-bit-rate=}'[Encode the video at the given bit-rate]' '--camera-ar=[Select the camera size by its aspect ratio]' @@ -30,7 +30,6 @@ arguments=( {-d,--select-usb}'[Use USB device]' '--disable-screensaver[Disable screensaver while scrcpy is running]' '--display-id=[Specify the display id to mirror]' - '--display-ime-policy[Set the policy for selecting where the IME should be displayed]' '--display-orientation=[Set the initial display orientation]:orientation values:(0 90 180 270 flip0 flip90 flip180 flip270)' {-e,--select-tcpip}'[Use TCP/IP device]' {-f,--fullscreen}'[Start in fullscreen]' diff --git a/app/deps/ffmpeg.sh b/app/deps/ffmpeg.sh index fb8b9a25..d268ca91 100755 --- a/app/deps/ffmpeg.sh +++ b/app/deps/ffmpeg.sh @@ -5,10 +5,10 @@ cd "$DEPS_DIR" . common process_args "$@" -VERSION=7.1.1 +VERSION=7.1 FILENAME=ffmpeg-$VERSION.tar.xz PROJECT_DIR=ffmpeg-$VERSION -SHA256SUM=733984395e0dbbe5c046abda2dc49a5544e7e0e1e2366bba849222ae9e3a03b1 +SHA256SUM=40973D44970DBC83EF302B0609F2E74982BE2D85916DD2EE7472D30678A7ABE6 cd "$SOURCES_DIR" diff --git a/app/deps/libusb.sh b/app/deps/libusb.sh index 4be03eb1..340b0f70 100755 --- a/app/deps/libusb.sh +++ b/app/deps/libusb.sh @@ -5,10 +5,10 @@ cd "$DEPS_DIR" . common process_args "$@" -VERSION=1.0.28 +VERSION=1.0.27 FILENAME=libusb-$VERSION.tar.gz PROJECT_DIR=libusb-$VERSION -SHA256SUM=378b3709a405065f8f9fb9f35e82d666defde4d342c2a1b181a9ac134d23c6fe +SHA256SUM=e8f18a7a36ecbb11fb820bd71540350d8f61bcd9db0d2e8c18a6fb80b214a3de cd "$SOURCES_DIR" diff --git a/app/deps/patches/SDL-pipewire-Ensure-that-the-correct-struct-is-used-for-.patch b/app/deps/patches/SDL-pipewire-Ensure-that-the-correct-struct-is-used-for-.patch deleted file mode 100644 index cbb516ec..00000000 --- a/app/deps/patches/SDL-pipewire-Ensure-that-the-correct-struct-is-used-for-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6be87ceb33a9aad3bf5204bb13b3a5e8b498fd26 Mon Sep 17 00:00:00 2001 -From: Neal Gompa -Date: Mon, 10 Feb 2025 05:00:56 -0500 -Subject: [PATCH] pipewire: Ensure that the correct struct is used for - enumeration APIs - -PipeWire now requires the correct struct type is used, otherwise -it will fail to compile. - -Reference: https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/188d920733f0791413d3386e5536ee7377f71b2f - -Fixes: https://github.com/libsdl-org/SDL/issues/12224 -(cherry picked from commit d35bef64e913dd7d5dd3153a4b61f10ef837dad6) ---- - src/audio/pipewire/SDL_pipewire.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c -index 889e05decb..5d1bfc28de 100644 ---- a/src/audio/pipewire/SDL_pipewire.c -+++ b/src/audio/pipewire/SDL_pipewire.c -@@ -590,7 +590,7 @@ static void node_event_info(void *object, const struct pw_node_info *info) - - /* Need to parse the parameters to get the sample rate */ - for (i = 0; i < info->n_params; ++i) { -- pw_node_enum_params(node->proxy, 0, info->params[i].id, 0, 0, NULL); -+ pw_node_enum_params((struct pw_node*)node->proxy, 0, info->params[i].id, 0, 0, NULL); - } - - hotplug_core_sync(node); --- -2.49.0 - diff --git a/app/deps/sdl.sh b/app/deps/sdl.sh index c3edee58..c098e367 100755 --- a/app/deps/sdl.sh +++ b/app/deps/sdl.sh @@ -5,10 +5,10 @@ cd "$DEPS_DIR" . common process_args "$@" -VERSION=2.32.2 +VERSION=2.30.10 FILENAME=SDL-$VERSION.tar.gz PROJECT_DIR=SDL-release-$VERSION -SHA256SUM=f2c7297ae7b3d3910a8b131e1e2a558fdd6d1a4443d5e345374d45cadfcb05a4 +SHA256SUM=35a8b9c4f3635d85762b904ac60ca4e0806bff89faeb269caafbe80860d67168 cd "$SOURCES_DIR" @@ -18,7 +18,6 @@ then else get_file "https://github.com/libsdl-org/SDL/archive/refs/tags/release-$VERSION.tar.gz" "$FILENAME" "$SHA256SUM" tar xf "$FILENAME" # First level directory is "$PROJECT_DIR" - patch -d "$PROJECT_DIR" -p1 < "$PATCHES_DIR"/SDL-pipewire-Ensure-that-the-correct-struct-is-used-for-.patch fi mkdir -p "$BUILD_DIR/$PROJECT_DIR" diff --git a/app/meson.build b/app/meson.build index f7df69eb..be02ebc1 100644 --- a/app/meson.build +++ b/app/meson.build @@ -192,19 +192,19 @@ datadir = get_option('datadir') # by default 'share' install_man('scrcpy.1') install_data('data/icon.png', rename: 'scrcpy.png', - install_dir: datadir / 'icons/hicolor/256x256/apps') + install_dir: join_paths(datadir, 'icons/hicolor/256x256/apps')) install_data('data/zsh-completion/_scrcpy', - install_dir: datadir / 'zsh/site-functions') + install_dir: join_paths(datadir, 'zsh/site-functions')) install_data('data/bash-completion/scrcpy', - install_dir: datadir / 'bash-completion/completions') + install_dir: join_paths(datadir, 'bash-completion/completions')) # Desktop entry file for application launchers if host_machine.system() == 'linux' # Install a launcher (ex: /usr/local/share/applications/scrcpy.desktop) install_data('data/scrcpy.desktop', - install_dir: datadir / 'applications') + install_dir: join_paths(datadir, 'applications')) install_data('data/scrcpy-console.desktop', - install_dir: datadir / 'applications') + install_dir: join_paths(datadir, 'applications')) endif @@ -279,9 +279,3 @@ if get_option('buildtype') == 'debug' test(t[0], exe) endforeach endif - -if meson.version().version_compare('>= 0.58.0') - devenv = environment() - devenv.set('SCRCPY_ICON_PATH', meson.current_source_dir() / 'data/icon.png') - meson.add_devenv(devenv) -endif diff --git a/app/scrcpy-windows.rc b/app/scrcpy-windows.rc index 19475e0b..2c441aa1 100644 --- a/app/scrcpy-windows.rc +++ b/app/scrcpy-windows.rc @@ -13,7 +13,7 @@ BEGIN VALUE "LegalCopyright", "Romain Vimont, Genymobile" VALUE "OriginalFilename", "scrcpy.exe" VALUE "ProductName", "scrcpy" - VALUE "ProductVersion", "3.2" + VALUE "ProductVersion", "3.1" END END BLOCK "VarFileInfo" diff --git a/app/scrcpy.1 b/app/scrcpy.1 index d481ddd1..924905e4 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -67,19 +67,13 @@ The available encoders can be listed by \fB\-\-list\-encoders\fR. .TP .BI "\-\-audio\-source " source -Select the audio source. Possible values are: +Select the audio source (output, mic or playback). - - "output": forwards the whole audio output, and disables playback on the device. - - "playback": captures the audio playback (Android apps can opt-out, so the whole output is not necessarily captured). - - "mic": captures the microphone. - - "mic-unprocessed": captures the microphone unprocessed (raw) sound. - - "mic-camcorder": captures the microphone tuned for video recording, with the same orientation as the camera if available. - - "mic-voice-recognition": captures the microphone tuned for voice recognition. - - "mic-voice-communication": captures the microphone tuned for voice communications (it will for instance take advantage of echo cancellation or automatic gain control if available). - - "voice-call": captures voice call. - - "voice-call-uplink": captures voice call uplink only. - - "voice-call-downlink": captures voice call downlink only. - - "voice-performance": captures audio meant to be processed for live performance (karaoke), includes both the microphone and the device playback. +The "output" source forwards the whole audio output, and disables playback on the device. + +The "playback" source captures the audio playback (Android apps can opt-out, so the whole output is not necessarily captured). + +The "mic" source captures the microphone. Default is output. @@ -167,19 +161,6 @@ The available display ids can be listed by \fB\-\-list\-displays\fR. Default is 0. -.TP -.BI "\-\-display\-ime\-policy " value -Set the policy for selecting where the IME should be displayed. - -Possible values are "local", "fallback" and "hide": - - - "local" means that the IME should appear on the local display. - - "fallback" means that the IME should appear on a fallback display (the default display). - - "hide" means that the IME should be hidden. - -By default, the IME policy is left unchanged. - - .TP .BI "\-\-display\-orientation " value Set the initial display orientation. @@ -408,7 +389,7 @@ Disable video playback on the computer. .TP .B \-\-no\-window -Disable scrcpy window. Implies --no-video-playback. +Disable scrcpy window. Implies --no-video-playback and --no-control. .TP .BI "\-\-orientation " value @@ -848,7 +829,7 @@ Report bugs to . .SH COPYRIGHT Copyright \(co 2018 Genymobile -Copyright \(co 2018\-2025 Romain Vimont +Copyright \(co 2018\-2024 Romain Vimont Licensed under the Apache License, Version 2.0. diff --git a/app/src/adb/adb.c b/app/src/adb/adb.c index 40e9e968..0cd3c0fd 100644 --- a/app/src/adb/adb.c +++ b/app/src/adb/adb.c @@ -4,10 +4,9 @@ #include #include #include -#include -#include "adb/adb_device.h" -#include "adb/adb_parser.h" +#include "adb_device.h" +#include "adb_parser.h" #include "util/env.h" #include "util/file.h" #include "util/log.h" diff --git a/app/src/adb/adb.h b/app/src/adb/adb.h index e4903902..43310fb9 100644 --- a/app/src/adb/adb.h +++ b/app/src/adb/adb.h @@ -6,7 +6,7 @@ #include #include -#include "adb/adb_device.h" +#include "adb_device.h" #include "util/intr.h" #define SC_ADB_NO_STDOUT (1 << 0) diff --git a/app/src/adb/adb_device.h b/app/src/adb/adb_device.h index 308663ef..56393bcf 100644 --- a/app/src/adb/adb_device.h +++ b/app/src/adb/adb_device.h @@ -4,6 +4,7 @@ #include "common.h" #include +#include #include "util/vector.h" diff --git a/app/src/adb/adb_parser.c b/app/src/adb/adb_parser.c index 90a1b30b..66bb1854 100644 --- a/app/src/adb/adb_parser.c +++ b/app/src/adb/adb_parser.c @@ -3,7 +3,6 @@ #include #include #include -#include #include "util/log.h" #include "util/str.h" diff --git a/app/src/adb/adb_parser.h b/app/src/adb/adb_parser.h index b8738a35..f20349f6 100644 --- a/app/src/adb/adb_parser.h +++ b/app/src/adb/adb_parser.h @@ -3,9 +3,9 @@ #include "common.h" -#include +#include -#include "adb/adb_device.h" +#include "adb_device.h" /** * Parse the available devices from the output of `adb devices` diff --git a/app/src/adb/adb_tunnel.c b/app/src/adb/adb_tunnel.c index 43e80e13..fa936e4b 100644 --- a/app/src/adb/adb_tunnel.c +++ b/app/src/adb/adb_tunnel.c @@ -1,11 +1,11 @@ #include "adb_tunnel.h" #include -#include -#include "adb/adb.h" +#include "adb.h" #include "util/log.h" #include "util/net_intr.h" +#include "util/process_intr.h" static bool listen_on_port(struct sc_intr *intr, sc_socket socket, uint16_t port) { diff --git a/app/src/audio_player.h b/app/src/audio_player.h index 5a66d43b..9133c24a 100644 --- a/app/src/audio_player.h +++ b/app/src/audio_player.h @@ -3,7 +3,9 @@ #include "common.h" -#include +#include +#include +#include #include "audio_regulator.h" #include "trait/frame_sink.h" diff --git a/app/src/audio_regulator.c b/app/src/audio_regulator.c index 16fdd08b..3e4f78ad 100644 --- a/app/src/audio_regulator.c +++ b/app/src/audio_regulator.c @@ -1,9 +1,5 @@ #include "audio_regulator.h" -#include -#include -#include -#include #include #include @@ -76,10 +72,8 @@ sc_audio_regulator_pull(struct sc_audio_regulator *ar, uint8_t *out, // Wait until the buffer is filled up to at least target_buffering // before playing if (buffered_samples < ar->target_buffering) { -#ifdef SC_AUDIO_REGULATOR_DEBUG - LOGD("[Audio] Inserting initial buffering silence: %" PRIu32 + LOGV("[Audio] Inserting initial buffering silence: %" PRIu32 " samples", out_samples); -#endif // Delay playback starting to reach the target buffering. Fill the // whole buffer with silence (len is small compared to the // arbitrary margin value). @@ -100,10 +94,8 @@ sc_audio_regulator_pull(struct sc_audio_regulator *ar, uint8_t *out, // dropped to keep the latency minimal. However, this would cause very // audible glitches, so let the clock compensation restore the target // latency. -#ifdef SC_AUDIO_REGULATOR_DEBUG LOGD("[Audio] Buffer underflow, inserting silence: %" PRIu32 " samples", silence); -#endif memset(out + TO_BYTES(read), 0, TO_BYTES(silence)); bool received = atomic_load_explicit(&ar->received, @@ -141,36 +133,6 @@ bool sc_audio_regulator_push(struct sc_audio_regulator *ar, const AVFrame *frame) { SwrContext *swr_ctx = ar->swr_ctx; - uint32_t input_samples = frame->nb_samples; - - assert(frame->pts >= 0); - int64_t pts = frame->pts; - if (ar->next_expected_pts && pts - ar->next_expected_pts > 100000) { - LOGV("[Audio] Discontinuity detected: %" PRIi64 "µs", - pts - ar->next_expected_pts); - // More than 100ms: consider it as a discontinuity - // (typically because silence packets were not captured) - uint32_t can_read = sc_audiobuf_can_read(&ar->buf); - if (input_samples + can_read < ar->target_buffering) { - // Adjust buffering to the target value directly - uint32_t silence = ar->target_buffering - can_read - input_samples; - sc_audiobuf_write_silence(&ar->buf, silence); - } - - // Reset state - ar->avg_buffering.avg = ar->target_buffering; - int ret = swr_set_compensation(swr_ctx, 0, 0); - (void) ret; - assert(!ret); // disabling compensation should never fail - ar->compensation_active = false; - ar->samples_since_resync = 0; - atomic_store_explicit(&ar->underflow, 0, memory_order_relaxed); - } - - int64_t packet_duration = input_samples * INT64_C(1000000) - / ar->sample_rate; - ar->next_expected_pts = pts + packet_duration; - int64_t swr_delay = swr_get_delay(swr_ctx, ar->sample_rate); // No need to av_rescale_rnd(), input and output sample rates are the same. // Add more space (256) for clock compensation. @@ -243,7 +205,6 @@ sc_audio_regulator_push(struct sc_audio_regulator *ar, const AVFrame *frame) { if (played) { underflow = atomic_exchange_explicit(&ar->underflow, 0, memory_order_relaxed); - ar->underflow_report += underflow; max_buffered_samples = ar->target_buffering * 11 / 10 + 60 * ar->sample_rate / 1000 /* 60 ms */; @@ -290,7 +251,7 @@ sc_audio_regulator_push(struct sc_audio_regulator *ar, const AVFrame *frame) { } // Number of samples added (or removed, if negative) for compensation - int32_t instant_compensation = (int32_t) written - input_samples; + int32_t instant_compensation = (int32_t) written - frame->nb_samples; // Inserting silence instantly increases buffering int32_t inserted_silence = (int32_t) underflow; // Dropping input samples instantly decreases buffering @@ -346,9 +307,7 @@ sc_audio_regulator_push(struct sc_audio_regulator *ar, const AVFrame *frame) { int abs_max_diff = distance / 50; diff = CLAMP(diff, -abs_max_diff, abs_max_diff); LOGV("[Audio] Buffering: target=%" PRIu32 " avg=%f cur=%" PRIu32 - " compensation=%d (underflow=%" PRIu32 ")", - ar->target_buffering, avg, can_read, diff, ar->underflow_report); - ar->underflow_report = 0; + " compensation=%d", ar->target_buffering, avg, can_read, diff); int ret = swr_set_compensation(swr_ctx, diff, distance); if (ret < 0) { @@ -431,9 +390,7 @@ sc_audio_regulator_init(struct sc_audio_regulator *ar, size_t sample_size, atomic_init(&ar->played, false); atomic_init(&ar->received, false); atomic_init(&ar->underflow, 0); - ar->underflow_report = 0; ar->compensation_active = false; - ar->next_expected_pts = 0; return true; diff --git a/app/src/audio_regulator.h b/app/src/audio_regulator.h index 4e18fe08..1c0eeb9f 100644 --- a/app/src/audio_regulator.h +++ b/app/src/audio_regulator.h @@ -5,8 +5,6 @@ #include #include -#include -#include #include #include #include "util/audiobuf.h" @@ -46,9 +44,6 @@ struct sc_audio_regulator { // Number of silence samples inserted since the last received packet atomic_uint_least32_t underflow; - // Number of silence samples inserted since the last log - uint32_t underflow_report; - // Non-zero compensation applied (only used by the receiver thread) bool compensation_active; @@ -57,9 +52,6 @@ struct sc_audio_regulator { // Set to true the first time samples are pulled by the player atomic_bool played; - - // PTS of the next expected packet (useful to detect discontinuities) - int64_t next_expected_pts; }; bool diff --git a/app/src/cli.c b/app/src/cli.c index b2e3e30a..ed1970d4 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include "options.h" @@ -14,7 +13,6 @@ #include "util/str.h" #include "util/strbuf.h" #include "util/term.h" -#include "util/tick.h" #define STR_IMPL_(x) #x #define STR(x) STR_IMPL_(x) @@ -113,7 +111,6 @@ enum { OPT_ANGLE, OPT_NO_VD_SYSTEM_DECORATIONS, OPT_NO_VD_DESTROY_CONTENT, - OPT_DISPLAY_IME_POLICY, }; struct sc_option { @@ -217,31 +214,13 @@ static const struct sc_option options[] = { .longopt_id = OPT_AUDIO_SOURCE, .longopt = "audio-source", .argdesc = "source", - .text = "Select the audio source. Possible values are:\n" - " - \"output\": forwards the whole audio output, and disables " - "playback on the device.\n" - " - \"playback\": captures the audio playback (Android apps " - "can opt-out, so the whole output is not necessarily " + .text = "Select the audio source (output, mic or playback).\n" + "The \"output\" source forwards the whole audio output, and " + "disables playback on the device.\n" + "The \"playback\" source captures the audio playback (Android " + "apps can opt-out, so the whole output is not necessarily " "captured).\n" - " - \"mic\": captures the microphone.\n" - " - \"mic-unprocessed\": captures the microphone unprocessed " - "(raw) sound.\n" - " - \"mic-camcorder\": captures the microphone tuned for video " - "recording, with the same orientation as the camera if " - "available.\n" - " - \"mic-voice-recognition\": captures the microphone tuned " - "for voice recognition.\n" - " - \"mic-voice-communication\": captures the microphone tuned " - "for voice communications (it will for instance take advantage " - "of echo cancellation or automatic gain control if " - "available).\n" - " - \"voice-call\": captures voice call.\n" - " - \"voice-call-uplink\": captures voice call uplink only.\n" - " - \"voice-call-downlink\": captures voice call downlink " - "only.\n" - " - \"voice-performance\": captures audio meant to be " - "processed for live performance (karaoke), includes both the " - "microphone and the device playback.\n" + "The \"mic\" source captures the microphone.\n" "Default is output.", }, { @@ -385,19 +364,6 @@ static const struct sc_option options[] = { " scrcpy --list-displays\n" "Default is 0.", }, - { - .longopt_id = OPT_DISPLAY_IME_POLICY, - .longopt = "display-ime-policy", - .argdesc = "value", - .text = "Set the policy for selecting where the IME should be " - "displayed.\n" - "Possible values are \"local\", \"fallback\" and \"hide\".\n" - "\"local\" means that the IME should appear on the local " - "display.\n" - "\"fallback\" means that the IME should appear on a fallback " - "display (the default display).\n" - "\"hide\" means that the IME should be hidden.", - }, { .longopt_id = OPT_DISPLAY_ORIENTATION, .longopt = "display-orientation", @@ -721,7 +687,8 @@ static const struct sc_option options[] = { { .longopt_id = OPT_NO_WINDOW, .longopt = "no-window", - .text = "Disable scrcpy window. Implies --no-video-playback.", + .text = "Disable scrcpy window. Implies --no-video-playback and " + "--no-control.", }, { .longopt_id = OPT_ORIENTATION, @@ -1646,25 +1613,6 @@ parse_audio_output_buffer(const char *s, sc_tick *tick) { return true; } -static bool -parse_display_ime_policy(const char *s, enum sc_display_ime_policy *policy) { - if (!strcmp(s, "local")) { - *policy = SC_DISPLAY_IME_POLICY_LOCAL; - return true; - } - if (!strcmp(s, "fallback")) { - *policy = SC_DISPLAY_IME_POLICY_FALLBACK; - return true; - } - if (!strcmp(s, "hide")) { - *policy = SC_DISPLAY_IME_POLICY_HIDE; - return true; - } - LOGE("Unsupported display IME policy: %s (expected local, fallback or " - "hide)", s); - return false; -} - static bool parse_orientation(const char *s, enum sc_orientation *orientation) { if (!strcmp(s, "0")) { @@ -2054,50 +2002,8 @@ parse_audio_source(const char *optarg, enum sc_audio_source *source) { return true; } - if (!strcmp(optarg, "mic-unprocessed")) { - *source = SC_AUDIO_SOURCE_MIC_UNPROCESSED; - return true; - } - - if (!strcmp(optarg, "mic-camcorder")) { - *source = SC_AUDIO_SOURCE_MIC_CAMCORDER; - return true; - } - - if (!strcmp(optarg, "mic-voice-recognition")) { - *source = SC_AUDIO_SOURCE_MIC_VOICE_RECOGNITION; - return true; - } - - if (!strcmp(optarg, "mic-voice-communication")) { - *source = SC_AUDIO_SOURCE_MIC_VOICE_COMMUNICATION; - return true; - } - - if (!strcmp(optarg, "voice-call")) { - *source = SC_AUDIO_SOURCE_VOICE_CALL; - return true; - } - - if (!strcmp(optarg, "voice-call-uplink")) { - *source = SC_AUDIO_SOURCE_VOICE_CALL_UPLINK; - return true; - } - - if (!strcmp(optarg, "voice-call-downlink")) { - *source = SC_AUDIO_SOURCE_VOICE_CALL_DOWNLINK; - return true; - } - - if (!strcmp(optarg, "voice-performance")) { - *source = SC_AUDIO_SOURCE_VOICE_PERFORMANCE; - return true; - } - - LOGE("Unsupported audio source: %s (expected output, mic, playback, " - "mic-unprocessed, mic-camcorder, mic-voice-recognition, " - "mic-voice-communication, voice-call, voice-call-uplink, " - "voice-call-downlink, voice-performance)", optarg); + LOGE("Unsupported audio source: %s (expected output, mic or playback)", + optarg); return false; } @@ -2815,12 +2721,6 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], case OPT_NO_VD_SYSTEM_DECORATIONS: opts->vd_system_decorations = false; break; - case OPT_DISPLAY_IME_POLICY: - if (!parse_display_ime_policy(optarg, - &opts->display_ime_policy)) { - return false; - } - break; default: // getopt prints the error message on stderr return false; @@ -2859,10 +2759,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], #endif if (!opts->window) { - // Without window, there cannot be any video playback + // Without window, there cannot be any video playback or control opts->video_playback = false; - // Controls are still possible, allowing for options like - // --turn-screen-off + opts->control = false; } if (!opts->video) { @@ -3077,12 +2976,6 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], return false; } - if (opts->display_ime_policy != SC_DISPLAY_IME_POLICY_UNDEFINED) { - LOGE("--display-ime-policy is only available with " - "--video-source=display"); - return false; - } - if (opts->camera_id && opts->camera_facing != SC_CAMERA_FACING_ANY) { LOGE("Cannot specify both --camera-id and --camera-facing"); return false; @@ -3124,12 +3017,6 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], return false; } - if (opts->display_ime_policy != SC_DISPLAY_IME_POLICY_UNDEFINED - && opts->display_id == 0 && !opts->new_display) { - LOGE("--display-ime-policy is only supported on a secondary display"); - return false; - } - if (opts->audio && opts->audio_source == SC_AUDIO_SOURCE_AUTO) { // Select the audio source according to the video source if (opts->video_source == SC_VIDEO_SOURCE_DISPLAY) { diff --git a/app/src/decoder.c b/app/src/decoder.c index 4d0a1daf..5d42b8b0 100644 --- a/app/src/decoder.c +++ b/app/src/decoder.c @@ -1,9 +1,11 @@ #include "decoder.h" -#include -#include -#include +#include +#include +#include +#include "events.h" +#include "trait/frame_sink.h" #include "util/log.h" /** Downcast packet_sink to decoder */ diff --git a/app/src/decoder.h b/app/src/decoder.h index 1f525fae..ba8903f4 100644 --- a/app/src/decoder.h +++ b/app/src/decoder.h @@ -3,11 +3,13 @@ #include "common.h" -#include - #include "trait/frame_source.h" #include "trait/packet_sink.h" +#include +#include +#include + struct sc_decoder { struct sc_packet_sink packet_sink; // packet sink trait struct sc_frame_source frame_source; // frame source trait diff --git a/app/src/delay_buffer.c b/app/src/delay_buffer.c index f75c6f72..e89a2092 100644 --- a/app/src/delay_buffer.c +++ b/app/src/delay_buffer.c @@ -2,7 +2,9 @@ #include #include -#include + +#include +#include #include "util/log.h" diff --git a/app/src/delay_buffer.h b/app/src/delay_buffer.h index 61cd77e4..18c1ce94 100644 --- a/app/src/delay_buffer.h +++ b/app/src/delay_buffer.h @@ -4,7 +4,6 @@ #include "common.h" #include -#include #include "clock.h" #include "trait/frame_source.h" diff --git a/app/src/demuxer.c b/app/src/demuxer.c index 885cd6ee..7223b553 100644 --- a/app/src/demuxer.c +++ b/app/src/demuxer.c @@ -1,11 +1,14 @@ #include "demuxer.h" #include -#include -#include #include +#include +#include +#include "decoder.h" +#include "events.h" #include "packet_merger.h" +#include "recorder.h" #include "util/binary.h" #include "util/log.h" diff --git a/app/src/demuxer.h b/app/src/demuxer.h index 2b7cb703..5587d12d 100644 --- a/app/src/demuxer.h +++ b/app/src/demuxer.h @@ -4,8 +4,12 @@ #include "common.h" #include +#include +#include +#include #include "trait/packet_source.h" +#include "trait/packet_sink.h" #include "util/net.h" #include "util/thread.h" diff --git a/app/src/device_msg.h b/app/src/device_msg.h index d6c701bb..86b2ccb7 100644 --- a/app/src/device_msg.h +++ b/app/src/device_msg.h @@ -3,9 +3,9 @@ #include "common.h" -#include +#include #include -#include +#include #define DEVICE_MSG_MAX_SIZE (1 << 18) // 256k // type: 1 byte; length: 4 bytes diff --git a/app/src/display.c b/app/src/display.c index aee8ef80..39018834 100644 --- a/app/src/display.c +++ b/app/src/display.c @@ -1,8 +1,6 @@ #include "display.h" #include -#include -#include #include #include "util/log.h" diff --git a/app/src/display.h b/app/src/display.h index 4de9b0a9..064bb7bf 100644 --- a/app/src/display.h +++ b/app/src/display.h @@ -4,8 +4,7 @@ #include "common.h" #include -#include -#include +#include #include #include "coords.h" diff --git a/app/src/events.c b/app/src/events.c index b4322d1b..ce885241 100644 --- a/app/src/events.c +++ b/app/src/events.c @@ -1,7 +1,5 @@ #include "events.h" -#include - #include "util/log.h" #include "util/thread.h" diff --git a/app/src/file_pusher.c b/app/src/file_pusher.c index 681fb5d6..06911052 100644 --- a/app/src/file_pusher.c +++ b/app/src/file_pusher.c @@ -1,11 +1,11 @@ #include "file_pusher.h" #include -#include #include #include "adb/adb.h" #include "util/log.h" +#include "util/process_intr.h" #define DEFAULT_PUSH_TARGET "/sdcard/Download/" diff --git a/app/src/fps_counter.c b/app/src/fps_counter.c index 1daa42ba..dd4ae1da 100644 --- a/app/src/fps_counter.c +++ b/app/src/fps_counter.c @@ -1,7 +1,6 @@ #include "fps_counter.h" #include -#include #include "util/log.h" diff --git a/app/src/fps_counter.h b/app/src/fps_counter.h index 3eab461c..e7619271 100644 --- a/app/src/fps_counter.h +++ b/app/src/fps_counter.h @@ -5,9 +5,9 @@ #include #include +#include #include "util/thread.h" -#include "util/tick.h" struct sc_fps_counter { sc_thread thread; diff --git a/app/src/frame_buffer.c b/app/src/frame_buffer.c index 9fd4cf6f..5699b58f 100644 --- a/app/src/frame_buffer.c +++ b/app/src/frame_buffer.c @@ -1,6 +1,8 @@ #include "frame_buffer.h" #include +#include +#include #include "util/log.h" diff --git a/app/src/frame_buffer.h b/app/src/frame_buffer.h index e748adfb..f97261cd 100644 --- a/app/src/frame_buffer.h +++ b/app/src/frame_buffer.h @@ -4,7 +4,6 @@ #include "common.h" #include -#include #include "util/thread.h" diff --git a/app/src/hid/hid_event.h b/app/src/hid/hid_event.h index b0d45ce8..d6818e30 100644 --- a/app/src/hid/hid_event.h +++ b/app/src/hid/hid_event.h @@ -3,7 +3,6 @@ #include "common.h" -#include #include #define SC_HID_MAX_SIZE 15 diff --git a/app/src/hid/hid_gamepad.c b/app/src/hid/hid_gamepad.c index 842eae9e..8f4e4527 100644 --- a/app/src/hid/hid_gamepad.c +++ b/app/src/hid/hid_gamepad.c @@ -2,8 +2,6 @@ #include #include -#include -#include #include "util/binary.h" #include "util/log.h" diff --git a/app/src/hid/hid_gamepad.h b/app/src/hid/hid_gamepad.h index 8d939ac7..b532a703 100644 --- a/app/src/hid/hid_gamepad.h +++ b/app/src/hid/hid_gamepad.h @@ -4,7 +4,6 @@ #include "common.h" #include -#include #include "hid/hid_event.h" #include "input_events.h" diff --git a/app/src/hid/hid_keyboard.c b/app/src/hid/hid_keyboard.c index 6477396a..961ad790 100644 --- a/app/src/hid/hid_keyboard.c +++ b/app/src/hid/hid_keyboard.c @@ -1,6 +1,5 @@ #include "hid_keyboard.h" -#include #include #include "util/log.h" diff --git a/app/src/hid/hid_keyboard.h b/app/src/hid/hid_keyboard.h index 5ecfd8cf..cde1ac52 100644 --- a/app/src/hid/hid_keyboard.h +++ b/app/src/hid/hid_keyboard.h @@ -4,7 +4,6 @@ #include "common.h" #include -#include #include "hid/hid_event.h" #include "input_events.h" diff --git a/app/src/hid/hid_mouse.c b/app/src/hid/hid_mouse.c index 29cfc594..7acc413b 100644 --- a/app/src/hid/hid_mouse.c +++ b/app/src/hid/hid_mouse.c @@ -1,7 +1,5 @@ #include "hid_mouse.h" -#include - // 1 byte for buttons + padding, 1 byte for X position, 1 byte for Y position, // 1 byte for wheel motion #define SC_HID_MOUSE_INPUT_SIZE 4 diff --git a/app/src/hid/hid_mouse.h b/app/src/hid/hid_mouse.h index 06c61dd1..a9a54718 100644 --- a/app/src/hid/hid_mouse.h +++ b/app/src/hid/hid_mouse.h @@ -3,6 +3,8 @@ #include "common.h" +#include + #include "hid/hid_event.h" #include "input_events.h" diff --git a/app/src/icon.c b/app/src/icon.c index 797afc75..4f3a9a39 100644 --- a/app/src/icon.c +++ b/app/src/icon.c @@ -2,22 +2,17 @@ #include #include -#include -#include -#include #include #include -#include #include #include -#include #include "config.h" +#include "compat.h" #include "util/env.h" -#ifdef PORTABLE -# include "util/file.h" -#endif +#include "util/file.h" #include "util/log.h" +#include "util/str.h" #define SCRCPY_PORTABLE_ICON_FILENAME "icon.png" #define SCRCPY_DEFAULT_ICON_PATH \ diff --git a/app/src/icon.h b/app/src/icon.h index 6bcf46d2..3251e48f 100644 --- a/app/src/icon.h +++ b/app/src/icon.h @@ -3,7 +3,9 @@ #include "common.h" -#include +#include +#include +#include SDL_Surface * scrcpy_icon_load(void); diff --git a/app/src/input_events.h b/app/src/input_events.h index 0c022acc..ad3afa81 100644 --- a/app/src/input_events.h +++ b/app/src/input_events.h @@ -9,6 +9,7 @@ #include #include "coords.h" +#include "options.h" /* The representation of input events in scrcpy is very close to the SDL API, * for simplicity. diff --git a/app/src/input_manager.c b/app/src/input_manager.c index 635825c9..2e4337db 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -1,12 +1,8 @@ #include "input_manager.h" #include -#include -#include -#include +#include -#include "android/input.h" -#include "android/keycodes.h" #include "input_events.h" #include "screen.h" #include "shortcut_mod.h" diff --git a/app/src/input_manager.h b/app/src/input_manager.h index af4cbc69..8efd0153 100644 --- a/app/src/input_manager.h +++ b/app/src/input_manager.h @@ -4,12 +4,12 @@ #include "common.h" #include -#include -#include -#include + +#include #include "controller.h" #include "file_pusher.h" +#include "fps_counter.h" #include "options.h" #include "trait/gamepad_processor.h" #include "trait/key_processor.h" diff --git a/app/src/keyboard_sdk.c b/app/src/keyboard_sdk.c index 466a1aeb..2d9ca85b 100644 --- a/app/src/keyboard_sdk.c +++ b/app/src/keyboard_sdk.c @@ -1,13 +1,8 @@ #include "keyboard_sdk.h" #include -#include -#include -#include -#include #include "android/input.h" -#include "android/keycodes.h" #include "control_msg.h" #include "controller.h" #include "input_events.h" diff --git a/app/src/main.c b/app/src/main.c index c58e0be7..8bbd074f 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -1,6 +1,9 @@ #include "common.h" +#include #include +#include +#include #ifdef HAVE_V4L2 # include #endif diff --git a/app/src/mouse_sdk.c b/app/src/mouse_sdk.c index 7eceffa7..a7998972 100644 --- a/app/src/mouse_sdk.c +++ b/app/src/mouse_sdk.c @@ -1,12 +1,12 @@ #include "mouse_sdk.h" #include -#include #include "android/input.h" #include "control_msg.h" #include "controller.h" #include "input_events.h" +#include "util/intmap.h" #include "util/log.h" /** Downcast mouse processor to sc_mouse_sdk */ diff --git a/app/src/mouse_sdk.h b/app/src/mouse_sdk.h index fe92a2d7..142b89bb 100644 --- a/app/src/mouse_sdk.h +++ b/app/src/mouse_sdk.h @@ -6,6 +6,7 @@ #include #include "controller.h" +#include "screen.h" #include "trait/mouse_processor.h" struct sc_mouse_sdk { diff --git a/app/src/opengl.c b/app/src/opengl.c index 0cb83ed7..376690af 100644 --- a/app/src/opengl.c +++ b/app/src/opengl.c @@ -2,8 +2,7 @@ #include #include -#include -#include +#include "SDL2/SDL.h" void sc_opengl_init(struct sc_opengl *gl) { diff --git a/app/src/options.c b/app/src/options.c index 0fe82d29..df8033e9 100644 --- a/app/src/options.c +++ b/app/src/options.c @@ -1,7 +1,5 @@ #include "options.h" -#include - const struct scrcpy_options scrcpy_options_default = { .serial = NULL, .crop = NULL, @@ -56,7 +54,6 @@ const struct scrcpy_options scrcpy_options_default = { .capture_orientation_lock = SC_ORIENTATION_UNLOCKED, .display_orientation = SC_ORIENTATION_0, .record_orientation = SC_ORIENTATION_0, - .display_ime_policy = SC_DISPLAY_IME_POLICY_UNDEFINED, .window_x = SC_WINDOW_POSITION_UNDEFINED, .window_y = SC_WINDOW_POSITION_UNDEFINED, .window_width = 0, diff --git a/app/src/options.h b/app/src/options.h index 03b42913..152881d8 100644 --- a/app/src/options.h +++ b/app/src/options.h @@ -5,6 +5,7 @@ #include #include +#include #include #include "util/tick.h" @@ -59,14 +60,6 @@ enum sc_audio_source { SC_AUDIO_SOURCE_OUTPUT, SC_AUDIO_SOURCE_MIC, SC_AUDIO_SOURCE_PLAYBACK, - SC_AUDIO_SOURCE_MIC_UNPROCESSED, - SC_AUDIO_SOURCE_MIC_CAMCORDER, - SC_AUDIO_SOURCE_MIC_VOICE_RECOGNITION, - SC_AUDIO_SOURCE_MIC_VOICE_COMMUNICATION, - SC_AUDIO_SOURCE_VOICE_CALL, - SC_AUDIO_SOURCE_VOICE_CALL_UPLINK, - SC_AUDIO_SOURCE_VOICE_CALL_DOWNLINK, - SC_AUDIO_SOURCE_VOICE_PERFORMANCE, }; enum sc_camera_facing { @@ -97,13 +90,6 @@ enum sc_orientation_lock { SC_ORIENTATION_LOCKED_INITIAL, // lock to initial device orientation }; -enum sc_display_ime_policy { - SC_DISPLAY_IME_POLICY_UNDEFINED, - SC_DISPLAY_IME_POLICY_LOCAL, - SC_DISPLAY_IME_POLICY_FALLBACK, - SC_DISPLAY_IME_POLICY_HIDE, -}; - static inline bool sc_orientation_is_mirror(enum sc_orientation orientation) { assert(!(orientation & ~7)); @@ -266,7 +252,6 @@ struct scrcpy_options { enum sc_orientation_lock capture_orientation_lock; enum sc_orientation display_orientation; enum sc_orientation record_orientation; - enum sc_display_ime_policy display_ime_policy; int16_t window_x; // SC_WINDOW_POSITION_UNDEFINED for "auto" int16_t window_y; // SC_WINDOW_POSITION_UNDEFINED for "auto" uint16_t window_width; diff --git a/app/src/packet_merger.c b/app/src/packet_merger.c index dea038b6..81b02d2c 100644 --- a/app/src/packet_merger.c +++ b/app/src/packet_merger.c @@ -1,9 +1,5 @@ #include "packet_merger.h" -#include -#include -#include - #include "util/log.h" void diff --git a/app/src/packet_merger.h b/app/src/packet_merger.h index 3f9972ce..e1824c2c 100644 --- a/app/src/packet_merger.h +++ b/app/src/packet_merger.h @@ -5,7 +5,7 @@ #include #include -#include +#include /** * Config packets (containing the SPS/PPS) are sent in-band. A new config diff --git a/app/src/receiver.c b/app/src/receiver.c index 2ccb8a8b..b89b0c6e 100644 --- a/app/src/receiver.c +++ b/app/src/receiver.c @@ -2,6 +2,7 @@ #include #include +#include #include #include "device_msg.h" diff --git a/app/src/recorder.c b/app/src/recorder.c index c26f8f2d..15f27157 100644 --- a/app/src/recorder.c +++ b/app/src/recorder.c @@ -1,9 +1,6 @@ #include "recorder.h" #include -#include -#include -#include #include #include #include diff --git a/app/src/recorder.h b/app/src/recorder.h index 70b73836..d096e79a 100644 --- a/app/src/recorder.h +++ b/app/src/recorder.h @@ -4,10 +4,9 @@ #include "common.h" #include -#include -#include #include +#include "coords.h" #include "options.h" #include "trait/packet_sink.h" #include "util/thread.h" diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index b3ff9b36..f1942e43 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -1,11 +1,10 @@ #include "scrcpy.h" -#include -#include -#include #include -#include #include +#include +#include +#include #include #ifdef _WIN32 @@ -38,9 +37,9 @@ #endif #include "util/acksync.h" #include "util/log.h" +#include "util/net.h" #include "util/rand.h" #include "util/timeout.h" -#include "util/tick.h" #ifdef HAVE_V4L2 # include "v4l2_sink.h" #endif @@ -436,7 +435,6 @@ scrcpy(struct scrcpy_options *options) { .control = options->control, .display_id = options->display_id, .new_display = options->new_display, - .display_ime_policy = options->display_ime_policy, .video = options->video, .audio = options->audio, .audio_dup = options->audio_dup, diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h index 7f6a0fb2..d4d494a3 100644 --- a/app/src/scrcpy.h +++ b/app/src/scrcpy.h @@ -3,6 +3,7 @@ #include "common.h" +#include #include "options.h" enum scrcpy_exit_code { diff --git a/app/src/screen.h b/app/src/screen.h index 6621b2d2..c716c399 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -1,14 +1,11 @@ -#ifndef SC_SCREEN_H -#define SC_SCREEN_H +#ifndef SCREEN_H +#define SCREEN_H #include "common.h" #include -#include #include -#include -#include -#include +#include #include "controller.h" #include "coords.h" @@ -17,6 +14,7 @@ #include "frame_buffer.h" #include "input_manager.h" #include "mouse_capture.h" +#include "opengl.h" #include "options.h" #include "trait/key_processor.h" #include "trait/frame_sink.h" diff --git a/app/src/server.c b/app/src/server.c index 153219c3..22ddd372 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -1,18 +1,19 @@ #include "server.h" #include +#include #include #include -#include -#include -#include +#include +#include #include "adb/adb.h" +#include "util/binary.h" #include "util/env.h" #include "util/file.h" #include "util/log.h" #include "util/net_intr.h" -#include "util/process.h" +#include "util/process_intr.h" #include "util/str.h" #define SC_SERVER_FILENAME "scrcpy-server" @@ -149,43 +150,12 @@ sc_server_get_audio_source_name(enum sc_audio_source audio_source) { return "mic"; case SC_AUDIO_SOURCE_PLAYBACK: return "playback"; - case SC_AUDIO_SOURCE_MIC_UNPROCESSED: - return "mic-unprocessed"; - case SC_AUDIO_SOURCE_MIC_CAMCORDER: - return "mic-camcorder"; - case SC_AUDIO_SOURCE_MIC_VOICE_RECOGNITION: - return "mic-voice-recognition"; - case SC_AUDIO_SOURCE_MIC_VOICE_COMMUNICATION: - return "mic-voice-communication"; - case SC_AUDIO_SOURCE_VOICE_CALL: - return "voice-call"; - case SC_AUDIO_SOURCE_VOICE_CALL_UPLINK: - return "voice-call-uplink"; - case SC_AUDIO_SOURCE_VOICE_CALL_DOWNLINK: - return "voice-call-downlink"; - case SC_AUDIO_SOURCE_VOICE_PERFORMANCE: - return "voice-performance"; default: assert(!"unexpected audio source"); return NULL; } } -static const char * -sc_server_get_display_ime_policy_name(enum sc_display_ime_policy policy) { - switch (policy) { - case SC_DISPLAY_IME_POLICY_LOCAL: - return "local"; - case SC_DISPLAY_IME_POLICY_FALLBACK: - return "fallback"; - case SC_DISPLAY_IME_POLICY_HIDE: - return "hide"; - default: - assert(!"unexpected display IME policy"); - return NULL; - } -} - static bool validate_string(const char *s) { // The parameters values are passed as command line arguments to adb, so @@ -407,10 +377,6 @@ execute_server(struct sc_server *server, VALIDATE_STRING(params->new_display); ADD_PARAM("new_display=%s", params->new_display); } - if (params->display_ime_policy != SC_DISPLAY_IME_POLICY_UNDEFINED) { - ADD_PARAM("display_ime_policy=%s", - sc_server_get_display_ime_policy_name(params->display_ime_policy)); - } if (!params->vd_destroy_content) { ADD_PARAM("vd_destroy_content=false"); } diff --git a/app/src/server.h b/app/src/server.h index 5f4592de..3c78b9ed 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -1,17 +1,19 @@ -#ifndef SC_SERVER_H -#define SC_SERVER_H +#ifndef SERVER_H +#define SERVER_H #include "common.h" +#include #include #include #include "adb/adb_tunnel.h" +#include "coords.h" #include "options.h" #include "util/intr.h" +#include "util/log.h" #include "util/net.h" #include "util/thread.h" -#include "util/tick.h" #define SC_DEVICE_NAME_FIELD_LENGTH 64 struct sc_server_info { @@ -50,7 +52,6 @@ struct sc_server_params { bool control; uint32_t display_id; const char *new_display; - enum sc_display_ime_policy display_ime_policy; bool video; bool audio; bool audio_dup; diff --git a/app/src/shortcut_mod.h b/app/src/shortcut_mod.h index f6c13f03..b685e987 100644 --- a/app/src/shortcut_mod.h +++ b/app/src/shortcut_mod.h @@ -3,7 +3,6 @@ #include "common.h" -#include #include #include #include diff --git a/app/src/sys/unix/file.c b/app/src/sys/unix/file.c index 8f7fb074..6123c788 100644 --- a/app/src/sys/unix/file.c +++ b/app/src/sys/unix/file.c @@ -1,11 +1,10 @@ #include "util/file.h" #include -#include #include +#include #include #include -#include #include #ifdef __APPLE__ # include // for _NSGetExecutablePath() diff --git a/app/src/sys/unix/process.c b/app/src/sys/unix/process.c index 36d1ff7d..8c4a53c3 100644 --- a/app/src/sys/unix/process.c +++ b/app/src/sys/unix/process.c @@ -4,8 +4,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/app/src/trait/frame_sink.h b/app/src/trait/frame_sink.h index 67be4d46..8ef248b6 100644 --- a/app/src/trait/frame_sink.h +++ b/app/src/trait/frame_sink.h @@ -3,6 +3,7 @@ #include "common.h" +#include #include #include diff --git a/app/src/trait/frame_source.c b/app/src/trait/frame_source.c index 56848309..416eccd9 100644 --- a/app/src/trait/frame_source.c +++ b/app/src/trait/frame_source.c @@ -1,7 +1,5 @@ #include "frame_source.h" -#include - void sc_frame_source_init(struct sc_frame_source *source) { source->sink_count = 0; diff --git a/app/src/trait/frame_source.h b/app/src/trait/frame_source.h index cb1ef905..94222af0 100644 --- a/app/src/trait/frame_source.h +++ b/app/src/trait/frame_source.h @@ -3,9 +3,7 @@ #include "common.h" -#include - -#include "trait/frame_sink.h" +#include "frame_sink.h" #define SC_FRAME_SOURCE_MAX_SINKS 2 diff --git a/app/src/trait/gamepad_processor.h b/app/src/trait/gamepad_processor.h index 5e8dc2a4..19629a9a 100644 --- a/app/src/trait/gamepad_processor.h +++ b/app/src/trait/gamepad_processor.h @@ -3,6 +3,9 @@ #include "common.h" +#include +#include + #include "input_events.h" /** diff --git a/app/src/trait/key_processor.h b/app/src/trait/key_processor.h index 9e9bb86e..96374413 100644 --- a/app/src/trait/key_processor.h +++ b/app/src/trait/key_processor.h @@ -3,6 +3,7 @@ #include "common.h" +#include #include #include "input_events.h" diff --git a/app/src/trait/mouse_processor.h b/app/src/trait/mouse_processor.h index d0a96e7c..6e0b596e 100644 --- a/app/src/trait/mouse_processor.h +++ b/app/src/trait/mouse_processor.h @@ -3,6 +3,7 @@ #include "common.h" +#include #include #include "input_events.h" diff --git a/app/src/trait/packet_sink.h b/app/src/trait/packet_sink.h index e12dea12..84cfe814 100644 --- a/app/src/trait/packet_sink.h +++ b/app/src/trait/packet_sink.h @@ -3,6 +3,7 @@ #include "common.h" +#include #include #include diff --git a/app/src/trait/packet_source.c b/app/src/trait/packet_source.c index 0a2c6c4d..c0836f1d 100644 --- a/app/src/trait/packet_source.c +++ b/app/src/trait/packet_source.c @@ -1,7 +1,5 @@ #include "packet_source.h" -#include - void sc_packet_source_init(struct sc_packet_source *source) { source->sink_count = 0; diff --git a/app/src/trait/packet_source.h b/app/src/trait/packet_source.h index 8788021a..16d56e86 100644 --- a/app/src/trait/packet_source.h +++ b/app/src/trait/packet_source.h @@ -3,9 +3,7 @@ #include "common.h" -#include - -#include "trait/packet_sink.h" +#include "packet_sink.h" #define SC_PACKET_SOURCE_MAX_SINKS 2 diff --git a/app/src/uhid/gamepad_uhid.c b/app/src/uhid/gamepad_uhid.c index c64feb18..a066cf03 100644 --- a/app/src/uhid/gamepad_uhid.c +++ b/app/src/uhid/gamepad_uhid.c @@ -1,10 +1,5 @@ #include "gamepad_uhid.h" -#include -#include -#include -#include - #include "hid/hid_gamepad.h" #include "input_events.h" #include "util/log.h" diff --git a/app/src/uhid/gamepad_uhid.h b/app/src/uhid/gamepad_uhid.h index ad747604..07d03099 100644 --- a/app/src/uhid/gamepad_uhid.h +++ b/app/src/uhid/gamepad_uhid.h @@ -3,6 +3,8 @@ #include "common.h" +#include + #include "controller.h" #include "hid/hid_gamepad.h" #include "trait/gamepad_processor.h" diff --git a/app/src/uhid/keyboard_uhid.c b/app/src/uhid/keyboard_uhid.c index 70082990..76d70cc5 100644 --- a/app/src/uhid/keyboard_uhid.c +++ b/app/src/uhid/keyboard_uhid.c @@ -1,12 +1,6 @@ #include "keyboard_uhid.h" -#include -#include -#include -#include - #include "util/log.h" -#include "util/thread.h" /** Downcast key processor to keyboard_uhid */ #define DOWNCAST(KP) container_of(KP, struct sc_keyboard_uhid, key_processor) diff --git a/app/src/uhid/mouse_uhid.c b/app/src/uhid/mouse_uhid.c index 7fed8383..471030e7 100644 --- a/app/src/uhid/mouse_uhid.c +++ b/app/src/uhid/mouse_uhid.c @@ -1,8 +1,5 @@ #include "mouse_uhid.h" -#include -#include - #include "hid/hid_mouse.h" #include "input_events.h" #include "util/log.h" diff --git a/app/src/uhid/uhid_output.c b/app/src/uhid/uhid_output.c index e743a73c..05e691da 100644 --- a/app/src/uhid/uhid_output.c +++ b/app/src/uhid/uhid_output.c @@ -1,5 +1,6 @@ #include "uhid_output.h" +#include #include #include "uhid/keyboard_uhid.h" diff --git a/app/src/uhid/uhid_output.h b/app/src/uhid/uhid_output.h index ed028b58..cd6a800f 100644 --- a/app/src/uhid/uhid_output.h +++ b/app/src/uhid/uhid_output.h @@ -3,7 +3,7 @@ #include "common.h" -#include +#include #include /** diff --git a/app/src/usb/aoa_hid.c b/app/src/usb/aoa_hid.c index 8cb62bfd..236a78ed 100644 --- a/app/src/usb/aoa_hid.c +++ b/app/src/usb/aoa_hid.c @@ -1,16 +1,13 @@ -#include "aoa_hid.h" +#include "util/log.h" #include #include #include -#include -#include -#include +#include "aoa_hid.h" #include "events.h" #include "util/log.h" #include "util/str.h" -#include "util/tick.h" #include "util/vector.h" // See . diff --git a/app/src/usb/aoa_hid.h b/app/src/usb/aoa_hid.h index 2755c957..9cc6355e 100644 --- a/app/src/usb/aoa_hid.h +++ b/app/src/usb/aoa_hid.h @@ -3,13 +3,16 @@ #include "common.h" -#include #include +#include + +#include #include "hid/hid_event.h" -#include "usb/usb.h" +#include "usb.h" #include "util/acksync.h" #include "util/thread.h" +#include "util/tick.h" #include "util/vecdeque.h" enum sc_aoa_event_type { diff --git a/app/src/usb/gamepad_aoa.c b/app/src/usb/gamepad_aoa.c index d29b1a78..4372379f 100644 --- a/app/src/usb/gamepad_aoa.c +++ b/app/src/usb/gamepad_aoa.c @@ -1,7 +1,5 @@ #include "gamepad_aoa.h" -#include - #include "input_events.h" #include "util/log.h" diff --git a/app/src/usb/gamepad_aoa.h b/app/src/usb/gamepad_aoa.h index 0297a365..b2dfbe5e 100644 --- a/app/src/usb/gamepad_aoa.h +++ b/app/src/usb/gamepad_aoa.h @@ -3,8 +3,10 @@ #include "common.h" +#include + +#include "aoa_hid.h" #include "hid/hid_gamepad.h" -#include "usb/aoa_hid.h" #include "trait/gamepad_processor.h" struct sc_gamepad_aoa { diff --git a/app/src/usb/keyboard_aoa.h b/app/src/usb/keyboard_aoa.h index 9e9500a3..565b9177 100644 --- a/app/src/usb/keyboard_aoa.h +++ b/app/src/usb/keyboard_aoa.h @@ -5,8 +5,8 @@ #include +#include "aoa_hid.h" #include "hid/hid_keyboard.h" -#include "usb/aoa_hid.h" #include "trait/key_processor.h" struct sc_keyboard_aoa { diff --git a/app/src/usb/mouse_aoa.c b/app/src/usb/mouse_aoa.c index b64e9b12..cb566cc0 100644 --- a/app/src/usb/mouse_aoa.c +++ b/app/src/usb/mouse_aoa.c @@ -1,7 +1,6 @@ #include "mouse_aoa.h" #include -#include #include "hid/hid_mouse.h" #include "input_events.h" diff --git a/app/src/usb/mouse_aoa.h b/app/src/usb/mouse_aoa.h index 506286ba..afaed761 100644 --- a/app/src/usb/mouse_aoa.h +++ b/app/src/usb/mouse_aoa.h @@ -5,7 +5,7 @@ #include -#include "usb/aoa_hid.h" +#include "aoa_hid.h" #include "trait/mouse_processor.h" struct sc_mouse_aoa { diff --git a/app/src/usb/scrcpy_otg.c b/app/src/usb/scrcpy_otg.c index 1a9cc46e..6ef2fc2a 100644 --- a/app/src/usb/scrcpy_otg.c +++ b/app/src/usb/scrcpy_otg.c @@ -1,19 +1,10 @@ #include "scrcpy_otg.h" -#include -#include -#include #include -#ifdef _WIN32 -# include "adb/adb.h" -#endif +#include "adb/adb.h" #include "events.h" -#include "usb/screen_otg.h" -#include "usb/aoa_hid.h" -#include "usb/gamepad_aoa.h" -#include "usb/keyboard_aoa.h" -#include "usb/mouse_aoa.h" +#include "screen_otg.h" #include "util/log.h" struct scrcpy_otg { diff --git a/app/src/usb/screen_otg.c b/app/src/usb/screen_otg.c index 02edc3a3..368af125 100644 --- a/app/src/usb/screen_otg.c +++ b/app/src/usb/screen_otg.c @@ -1,11 +1,7 @@ #include "screen_otg.h" -#include -#include - #include "icon.h" #include "options.h" -#include "util/acksync.h" #include "util/log.h" static void diff --git a/app/src/usb/screen_otg.h b/app/src/usb/screen_otg.h index 08b76ae7..427723ad 100644 --- a/app/src/usb/screen_otg.h +++ b/app/src/usb/screen_otg.h @@ -4,13 +4,12 @@ #include "common.h" #include -#include #include +#include "keyboard_aoa.h" +#include "mouse_aoa.h" #include "mouse_capture.h" -#include "usb/gamepad_aoa.h" -#include "usb/keyboard_aoa.h" -#include "usb/mouse_aoa.h" +#include "gamepad_aoa.h" struct sc_screen_otg { struct sc_keyboard_aoa *keyboard; diff --git a/app/src/util/acksync.c b/app/src/util/acksync.c index 76ecee0d..2899cdcb 100644 --- a/app/src/util/acksync.c +++ b/app/src/util/acksync.c @@ -1,6 +1,7 @@ #include "acksync.h" #include +#include "util/log.h" bool sc_acksync_init(struct sc_acksync *as) { diff --git a/app/src/util/acksync.h b/app/src/util/acksync.h index 3d9c9b2f..58ab1b35 100644 --- a/app/src/util/acksync.h +++ b/app/src/util/acksync.h @@ -3,10 +3,7 @@ #include "common.h" -#include -#include -#include "util/thread.h" -#include "util/tick.h" +#include "thread.h" #define SC_SEQUENCE_INVALID 0 diff --git a/app/src/util/audiobuf.c b/app/src/util/audiobuf.c index eeb27514..3cc5cad1 100644 --- a/app/src/util/audiobuf.c +++ b/app/src/util/audiobuf.c @@ -116,38 +116,3 @@ sc_audiobuf_write(struct sc_audiobuf *buf, const void *from_, return samples_count; } - -uint32_t -sc_audiobuf_write_silence(struct sc_audiobuf *buf, uint32_t samples_count) { - // Only the writer thread can write head, so memory_order_relaxed is - // sufficient - uint32_t head = atomic_load_explicit(&buf->head, memory_order_relaxed); - - // The tail cursor is updated after the data is consumed by the reader - uint32_t tail = atomic_load_explicit(&buf->tail, memory_order_acquire); - - uint32_t can_write = (buf->alloc_size + tail - head - 1) % buf->alloc_size; - if (!can_write) { - return 0; - } - if (samples_count > can_write) { - samples_count = can_write; - } - - uint32_t right_count = buf->alloc_size - head; - if (right_count > samples_count) { - right_count = samples_count; - } - memset(buf->data + (head * buf->sample_size), 0, - right_count * buf->sample_size); - - if (samples_count > right_count) { - uint32_t left_count = samples_count - right_count; - memset(buf->data, 0, left_count * buf->sample_size); - } - - uint32_t new_head = (head + samples_count) % buf->alloc_size; - atomic_store_explicit(&buf->head, new_head, memory_order_release); - - return samples_count; -} diff --git a/app/src/util/audiobuf.h b/app/src/util/audiobuf.h index b55a5a59..5e7dd4a0 100644 --- a/app/src/util/audiobuf.h +++ b/app/src/util/audiobuf.h @@ -6,7 +6,6 @@ #include #include #include -#include #include /** @@ -50,9 +49,6 @@ uint32_t sc_audiobuf_write(struct sc_audiobuf *buf, const void *from, uint32_t samples_count); -uint32_t -sc_audiobuf_write_silence(struct sc_audiobuf *buf, uint32_t samples); - static inline uint32_t sc_audiobuf_capacity(struct sc_audiobuf *buf) { assert(buf->alloc_size); diff --git a/app/src/util/average.h b/app/src/util/average.h index eded9987..59fae7d1 100644 --- a/app/src/util/average.h +++ b/app/src/util/average.h @@ -3,6 +3,9 @@ #include "common.h" +#include +#include + struct sc_average { // Current average value float avg; diff --git a/app/src/util/binary.h b/app/src/util/binary.h index b6ce3201..7de9b505 100644 --- a/app/src/util/binary.h +++ b/app/src/util/binary.h @@ -4,6 +4,7 @@ #include "common.h" #include +#include #include static inline void diff --git a/app/src/util/env.c b/app/src/util/env.c index 127f5a1f..1128e5ea 100644 --- a/app/src/util/env.c +++ b/app/src/util/env.c @@ -2,9 +2,7 @@ #include #include -#ifdef _WIN32 -# include "util/str.h" -#endif +#include "util/str.h" char * sc_get_env(const char *varname) { diff --git a/app/src/util/intmap.h b/app/src/util/intmap.h index 7ab903ca..2898c461 100644 --- a/app/src/util/intmap.h +++ b/app/src/util/intmap.h @@ -3,7 +3,6 @@ #include "common.h" -#include #include struct sc_intmap_entry { diff --git a/app/src/util/intr.c b/app/src/util/intr.c index ddf4839f..22bd121a 100644 --- a/app/src/util/intr.c +++ b/app/src/util/intr.c @@ -1,9 +1,9 @@ #include "intr.h" -#include - #include "util/log.h" +#include + bool sc_intr_init(struct sc_intr *intr) { bool ok = sc_mutex_init(&intr->mutex); diff --git a/app/src/util/intr.h b/app/src/util/intr.h index 35bd3375..1c20f6df 100644 --- a/app/src/util/intr.h +++ b/app/src/util/intr.h @@ -6,9 +6,9 @@ #include #include -#include "util/net.h" -#include "util/process.h" -#include "util/thread.h" +#include "net.h" +#include "process.h" +#include "thread.h" /** * Interruptor to wake up a blocking call from another thread diff --git a/app/src/util/log.c b/app/src/util/log.c index 9114a258..8a347c84 100644 --- a/app/src/util/log.c +++ b/app/src/util/log.c @@ -4,10 +4,7 @@ # include #endif #include -#include -#include -#include -#include +#include static SDL_LogPriority log_level_sc_to_sdl(enum sc_log_level level) { diff --git a/app/src/util/net.c b/app/src/util/net.c index 9562ff6b..d68b0af6 100644 --- a/app/src/util/net.c +++ b/app/src/util/net.c @@ -1,27 +1,28 @@ #include "net.h" #include +#include #include +#include "log.h" + #ifdef _WIN32 # include typedef int socklen_t; #else -# include -# include +# include +# include # include # include +# include # include -# include -# include +# include # define SOCKET_ERROR -1 typedef struct sockaddr_in SOCKADDR_IN; typedef struct sockaddr SOCKADDR; typedef struct in_addr IN_ADDR; #endif -#include "util/log.h" - bool net_init(void) { #ifdef _WIN32 diff --git a/app/src/util/net.h b/app/src/util/net.h index aa99bbc4..94789954 100644 --- a/app/src/util/net.h +++ b/app/src/util/net.h @@ -4,15 +4,14 @@ #include "common.h" #include -#include #include -#include #ifdef _WIN32 # include typedef SOCKET sc_raw_socket; # define SC_RAW_SOCKET_NONE INVALID_SOCKET #else // not _WIN32 +# include typedef int sc_raw_socket; # define SC_RAW_SOCKET_NONE -1 #endif diff --git a/app/src/util/net_intr.h b/app/src/util/net_intr.h index e2bbee88..dbef528d 100644 --- a/app/src/util/net_intr.h +++ b/app/src/util/net_intr.h @@ -3,13 +3,8 @@ #include "common.h" -#include -#include -#include -#include - -#include "util/intr.h" -#include "util/net.h" +#include "intr.h" +#include "net.h" bool net_connect_intr(struct sc_intr *intr, sc_socket socket, uint32_t addr, diff --git a/app/src/util/process.c b/app/src/util/process.c index 29d89a54..9c4dcd9f 100644 --- a/app/src/util/process.c +++ b/app/src/util/process.c @@ -1,6 +1,8 @@ #include "process.h" #include +#include +#include "log.h" enum sc_process_result sc_process_execute(const char *const argv[], sc_pid *pid, unsigned flags) { diff --git a/app/src/util/process.h b/app/src/util/process.h index eec51bcc..4d9d1684 100644 --- a/app/src/util/process.h +++ b/app/src/util/process.h @@ -4,9 +4,7 @@ #include "common.h" #include -#include #include "util/thread.h" -#include "util/tick.h" #ifdef _WIN32 diff --git a/app/src/util/process_intr.c b/app/src/util/process_intr.c index 641440ab..d37bd5a5 100644 --- a/app/src/util/process_intr.c +++ b/app/src/util/process_intr.c @@ -5,7 +5,7 @@ sc_pipe_read_intr(struct sc_intr *intr, sc_pid pid, sc_pipe pipe, char *data, size_t len) { if (intr && !sc_intr_set_process(intr, pid)) { // Already interrupted - return -1; + return false; } ssize_t ret = sc_pipe_read(pipe, data, len); @@ -22,7 +22,7 @@ sc_pipe_read_all_intr(struct sc_intr *intr, sc_pid pid, sc_pipe pipe, char *data, size_t len) { if (intr && !sc_intr_set_process(intr, pid)) { // Already interrupted - return -1; + return false; } ssize_t ret = sc_pipe_read_all(pipe, data, len); diff --git a/app/src/util/process_intr.h b/app/src/util/process_intr.h index 020eafa1..530a9046 100644 --- a/app/src/util/process_intr.h +++ b/app/src/util/process_intr.h @@ -3,8 +3,8 @@ #include "common.h" -#include "util/intr.h" -#include "util/process.h" +#include "intr.h" +#include "process.h" ssize_t sc_pipe_read_intr(struct sc_intr *intr, sc_pid pid, sc_pipe pipe, char *data, diff --git a/app/src/util/str.c b/app/src/util/str.c index 83d19c4d..304cd302 100644 --- a/app/src/util/str.c +++ b/app/src/util/str.c @@ -12,8 +12,8 @@ # include #endif -#include "util/log.h" -#include "util/strbuf.h" +#include "log.h" +#include "strbuf.h" size_t sc_strncpy(char *dest, const char *src, size_t n) { diff --git a/app/src/util/str.h b/app/src/util/str.h index b386b48d..d20f1b28 100644 --- a/app/src/util/str.h +++ b/app/src/util/str.h @@ -5,8 +5,6 @@ #include #include -#include -#include /* Stringify a numeric value */ #define SC_STR(s) SC_XSTR(s) diff --git a/app/src/util/strbuf.c b/app/src/util/strbuf.c index 6196d746..1892b46b 100644 --- a/app/src/util/strbuf.c +++ b/app/src/util/strbuf.c @@ -1,10 +1,11 @@ #include "strbuf.h" #include +#include #include #include -#include "util/log.h" +#include "log.h" bool sc_strbuf_init(struct sc_strbuf *buf, size_t init_cap) { diff --git a/app/src/util/thread.c b/app/src/util/thread.c index 2a5253f7..9679dfff 100644 --- a/app/src/util/thread.c +++ b/app/src/util/thread.c @@ -1,12 +1,10 @@ #include "thread.h" #include -#include -#include #include #include -#include "util/log.h" +#include "log.h" sc_thread_id SC_MAIN_THREAD_ID; diff --git a/app/src/util/tick.c b/app/src/util/tick.c index edef1070..cc0bab5e 100644 --- a/app/src/util/tick.c +++ b/app/src/util/tick.c @@ -1,7 +1,6 @@ #include "tick.h" #include -#include #include #ifdef _WIN32 # include diff --git a/app/src/util/timeout.c b/app/src/util/timeout.c index 21bc3a53..159a4681 100644 --- a/app/src/util/timeout.c +++ b/app/src/util/timeout.c @@ -1,9 +1,8 @@ #include "timeout.h" #include -#include -#include "util/log.h" +#include "log.h" bool sc_timeout_init(struct sc_timeout *timeout) { diff --git a/app/src/util/timeout.h b/app/src/util/timeout.h index a45ae2ae..ae171b86 100644 --- a/app/src/util/timeout.h +++ b/app/src/util/timeout.h @@ -5,8 +5,8 @@ #include -#include "util/thread.h" -#include "util/tick.h" +#include "thread.h" +#include "tick.h" struct sc_timeout { sc_thread thread; diff --git a/app/src/util/vecdeque.h b/app/src/util/vecdeque.h index e31724e2..ce559ee9 100644 --- a/app/src/util/vecdeque.h +++ b/app/src/util/vecdeque.h @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/app/src/util/vector.h b/app/src/util/vector.h index 5b399d56..97d7c389 100644 --- a/app/src/util/vector.h +++ b/app/src/util/vector.h @@ -5,8 +5,8 @@ #include #include -#include #include +#include // Adapted from vlc_vector: // diff --git a/app/src/v4l2_sink.c b/app/src/v4l2_sink.c index da9e02ef..087e9af4 100644 --- a/app/src/v4l2_sink.c +++ b/app/src/v4l2_sink.c @@ -1,9 +1,5 @@ #include "v4l2_sink.h" -#include -#include -#include -#include #include #include "util/log.h" diff --git a/app/src/v4l2_sink.h b/app/src/v4l2_sink.h index 2b7c5b50..365a739d 100644 --- a/app/src/v4l2_sink.h +++ b/app/src/v4l2_sink.h @@ -3,13 +3,13 @@ #include "common.h" -#include #include #include -#include "frame_buffer.h" +#include "coords.h" #include "trait/frame_sink.h" -#include "util/thread.h" +#include "frame_buffer.h" +#include "util/tick.h" struct sc_v4l2_sink { struct sc_frame_sink frame_sink; // frame sink trait diff --git a/app/src/version.c b/app/src/version.c index f8610714..90ea3334 100644 --- a/app/src/version.c +++ b/app/src/version.c @@ -1,6 +1,5 @@ #include "version.h" -#include #include #include #include @@ -10,7 +9,6 @@ #ifdef HAVE_USB # include #endif -#include void scrcpy_print_version(void) { diff --git a/app/tests/test_audiobuf.c b/app/tests/test_audiobuf.c index 539ee238..94d0f07a 100644 --- a/app/tests/test_audiobuf.c +++ b/app/tests/test_audiobuf.c @@ -113,14 +113,6 @@ static void test_audiobuf_partial_read_write(void) { uint32_t expected2[] = {4, 5, 6, 1, 2, 3, 4, 1, 2, 3}; assert(!memcmp(data, expected2, 12)); - w = sc_audiobuf_write_silence(&buf, 4); - assert(w == 4); - - r = sc_audiobuf_read(&buf, data, 4); - assert(r == 4); - uint32_t expected3[] = {0, 0, 0, 0}; - assert(!memcmp(data, expected3, 4)); - sc_audiobuf_destroy(&buf); } diff --git a/cross_win32.txt b/cross_win32.txt index ddbc65f3..05f9a86b 100644 --- a/cross_win32.txt +++ b/cross_win32.txt @@ -7,8 +7,6 @@ cpp = 'i686-w64-mingw32-g++' ar = 'i686-w64-mingw32-ar' strip = 'i686-w64-mingw32-strip' pkg-config = 'i686-w64-mingw32-pkg-config' -# backward compatibility -pkgconfig = 'i686-w64-mingw32-pkg-config' windres = 'i686-w64-mingw32-windres' [host_machine] diff --git a/cross_win64.txt b/cross_win64.txt index a6f16e16..86364ad6 100644 --- a/cross_win64.txt +++ b/cross_win64.txt @@ -7,8 +7,6 @@ cpp = 'x86_64-w64-mingw32-g++' ar = 'x86_64-w64-mingw32-ar' strip = 'x86_64-w64-mingw32-strip' pkg-config = 'x86_64-w64-mingw32-pkg-config' -# backward compatibility -pkgconfig = 'x86_64-w64-mingw32-pkg-config' windres = 'x86_64-w64-mingw32-windres' [host_machine] diff --git a/doc/audio.md b/doc/audio.md index 142626f5..85f76ac5 100644 --- a/doc/audio.md +++ b/doc/audio.md @@ -66,20 +66,6 @@ the computer: scrcpy --audio-source=mic --no-video --no-playback --record=file.opus ``` -Many sources are available: - - - `output` (default): forwards the whole audio output, and disables playback on the device (mapped to [`REMOTE_SUBMIX`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#REMOTE_SUBMIX)). - - `playback`: captures the audio playback (Android apps can opt-out, so the whole output is not necessarily captured). - - `mic`: captures the microphone (mapped to [`MIC`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#MIC)). - - `mic-unprocessed`: captures the microphone unprocessed (raw) sound (mapped to [`UNPROCESSED`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#UNPROCESSED)). - - `mic-camcorder`: captures the microphone tuned for video recording, with the same orientation as the camera if available (mapped to [`CAMCORDER`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#CAMCORDER)). - - `mic-voice-recognition`: captures the microphone tuned for voice recognition (mapped to [`VOICE_RECOGNITION`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#VOICE_RECOGNITION)). - - `mic-voice-communication`: captures the microphone tuned for voice communications (it will for instance take advantage of echo cancellation or automatic gain control if available) (mapped to [`VOICE_COMMUNICATION`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#VOICE_COMMUNICATION)). - - `voice-call`: captures voice call (mapped to [`VOICE_CALL`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#VOICE_CALL)). - - `voice-call-uplink`: captures voice call uplink only (mapped to [`VOICE_UPLINK`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#VOICE_UPLINK)). - - `voice-call-downlink`: captures voice call downlink only (mapped to [`VOICE_DOWNLINK`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#VOICE_DOWNLINK)). - - `voice-performance`: captures audio meant to be processed for live performance (karaoke), includes both the microphone and the device playback (mapped to [`VOICE_PERFORMANCE`](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource#VOICE_PERFORMANCE)). - ### Duplication An alternative device audio capture method is also available (only for Android diff --git a/doc/build.md b/doc/build.md index afe8b21b..2776ed01 100644 --- a/doc/build.md +++ b/doc/build.md @@ -233,10 +233,10 @@ install` must be run as root)._ #### Option 2: Use prebuilt server - - [`scrcpy-server-v3.2`][direct-scrcpy-server] - SHA-256: `b920e0ea01936bf2482f4ba2fa985c22c13c621999e3d33b45baa5acfc1ea3d0` + - [`scrcpy-server-v3.1`][direct-scrcpy-server] + SHA-256: `958f0944a62f23b1f33a16e9eb14844c1a04b882ca175a738c16d23cb22b86c0` -[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v3.2/scrcpy-server-v3.2 +[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-server-v3.1 Download the prebuilt server somewhere, and specify its path during the Meson configuration: diff --git a/doc/connection.md b/doc/connection.md index dcf00147..2c3d37e1 100644 --- a/doc/connection.md +++ b/doc/connection.md @@ -113,17 +113,16 @@ with the device IP address you found)_. 7. Run `scrcpy` as usual. 8. Run `adb disconnect` once you're done. -Since Android 11, a [wireless debugging option][adb-wireless] allows you to -bypass having to physically connect your device to your computer. +Since Android 11, a [wireless debugging option][adb-wireless] allows to bypass +having to physically connect your device directly to your computer. [adb-wireless]: https://developer.android.com/studio/command-line/adb#wireless-android11-command-line ## Autostart -A small tool (by the scrcpy author) allows you to run arbitrary commands -whenever a new Android device is connected: [AutoAdb]. It can be used to start -scrcpy: +A small tool (by the scrcpy author) allows to run arbitrary commands whenever a +new Android device is connected: [AutoAdb]. It can be used to start scrcpy: ```bash autoadb scrcpy -s '{}' diff --git a/doc/device.md b/doc/device.md index ab1e6ba4..42208faa 100644 --- a/doc/device.md +++ b/doc/device.md @@ -34,31 +34,6 @@ adb shell settings put global stay_on_while_plugged_in 0 ``` -## Screen off timeout - -The Android screen automatically turns off after some delay. - -To change this delay while scrcpy is running: - -```bash -scrcpy --screen-off-timeout=300 # 300 seconds (5 minutes) -``` - -The initial value is restored on exit. - -It is possible to change this setting manually: - -```bash -# get the current screen_off_timeout value -adb shell settings get system screen_off_timeout -# set a new value (in milliseconds) -adb shell settings put system screen_off_timeout 30000 -``` - -Note that the Android value is in milliseconds, but the scrcpy command line -argument is in seconds. - - ## Turn screen off It is possible to turn the device screen off while mirroring on start with a @@ -96,6 +71,31 @@ adb shell cmd display power-on 0 ``` +## Screen off timeout + +The Android screen automatically turns off after some delay. + +To change this delay while scrcpy is running: + +```bash +scrcpy --screen-off-timeout=300 # 300 seconds (5 minutes) +``` + +The initial value is restored on exit. + +It is possible to change this setting manually: + +```bash +# get the current screen_off_timeout value +adb shell settings get system screen_off_timeout +# set a new value (in milliseconds) +adb shell settings put system screen_off_timeout 30000 +``` + +Note that the Android value is in milliseconds, but the scrcpy command line +argument is in seconds. + + ## Show touches For presentations, it may be useful to show physical touches (on the physical diff --git a/doc/linux.md b/doc/linux.md index 979ef568..9beaed1e 100644 --- a/doc/linux.md +++ b/doc/linux.md @@ -6,11 +6,11 @@ Download a static build of the [latest release]: - - [`scrcpy-linux-x86_64-v3.2.tar.gz`][direct-linux-x86_64] (x86_64) - SHA-256: `df6cf000447428fcde322022848d655ff0211d98688d0f17cbbf21be9c1272be` + - [`scrcpy-linux-x86_64-v3.1.tar.gz`][direct-linux-x86_64] (x86_64) + SHA-256: `37dba54092ed9ec6b2f8f95432f61b8ea124aec9f1e9f2b3d22d4b10bb04c59a` [latest release]: https://github.com/Genymobile/scrcpy/releases/latest -[direct-linux-x86_64]: https://github.com/Genymobile/scrcpy/releases/download/v3.2/scrcpy-linux-x86_64-v3.2.tar.gz +[direct-linux-x86_64]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-linux-x86_64-v3.1.tar.gz and extract it. @@ -27,7 +27,7 @@ Scrcpy is packaged in several distributions and package managers: - Arch Linux: `pacman -S scrcpy` - Fedora: `dnf copr enable zeno/scrcpy && dnf install scrcpy` - Gentoo: `emerge scrcpy` - - Snap: ~~`snap install scrcpy`~~ _(obsolete version)_ + - Snap: `snap install scrcpy` - … (see [repology](https://repology.org/project/scrcpy/versions)) diff --git a/doc/macos.md b/doc/macos.md index b0335d18..56d9f168 100644 --- a/doc/macos.md +++ b/doc/macos.md @@ -6,15 +6,15 @@ Download a static build of the [latest release]: - - [`scrcpy-macos-aarch64-v3.2.tar.gz`][direct-macos-aarch64] (aarch64) - SHA-256: `f6d1f3c5f74d4d46f5080baa5b56b69f5edbf698d47e0cf4e2a1fd5058f9507b` + - [`scrcpy-macos-aarch64-v3.1.tar.gz`][direct-macos-aarch64] (aarch64) + SHA-256: `478618d940421e5f57942f5479d493ecbb38210682937a200f712aee5f235daf` - - [`scrcpy-macos-x86_64-v3.2.tar.gz`][direct-macos-x86_64] (x86_64) - SHA-256: `e337d5cf0ba4e1281699c338ce5f104aee96eb7b2893dc851399b6643eb4044e` + - [`scrcpy-macos-x86_64-v3.1.tar.gz`][direct-macos-x86_64] (x86_64) + SHA-256: `acde98e29c273710ffa469371dbca4a728a44c41c380381f8a54e5b5301b9e87` [latest release]: https://github.com/Genymobile/scrcpy/releases/latest -[direct-macos-aarch64]: https://github.com/Genymobile/scrcpy/releases/download/v3.2/scrcpy-macos-aarch64-v3.2.tar.gz -[direct-macos-x86_64]: https://github.com/Genymobile/scrcpy/releases/download/v3.2/scrcpy-macos-x86_64-v3.2.tar.gz +[direct-macos-aarch64]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-macos-aarch64-v3.1.tar.gz +[direct-macos-x86_64]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-macos-x86_64-v3.1.tar.gz and extract it. diff --git a/doc/mouse.md b/doc/mouse.md index 0bea4aea..3607a92c 100644 --- a/doc/mouse.md +++ b/doc/mouse.md @@ -83,9 +83,9 @@ process like the _adb daemon_). ## Mouse bindings By default, with SDK mouse: - - right-click triggers `BACK` (or `POWER` on) - - middle-click triggers `HOME` - - the 4th click triggers `APP_SWITCH` + - right-click triggers BACK (or POWER on) + - middle-click triggers HOME + - the 4th click triggers APP_SWITCH - the 5th click expands the notification panel The secondary clicks may be forwarded to the device instead by pressing the @@ -121,9 +121,9 @@ Each character must be one of the following: - `+`: forward the click to the device - `-`: ignore the click - - `b`: trigger shortcut `BACK` (or turn screen on if off) - - `h`: trigger shortcut `HOME` - - `s`: trigger shortcut `APP_SWITCH` + - `b`: trigger shortcut BACK (or turn screen on if off) + - `h`: trigger shortcut HOME + - `s`: trigger shortcut APP_SWITCH - `n`: trigger shortcut "expand notification panel" For example: diff --git a/doc/virtual_display.md b/doc/virtual_display.md index 9f962127..5d1673e8 100644 --- a/doc/virtual_display.md +++ b/doc/virtual_display.md @@ -11,8 +11,6 @@ scrcpy --new-display # use the main display size and density scrcpy --new-display=/240 # use the main display size and 240 dpi ``` -The new virtual display is destroyed on exit. - ## Start app On some devices, a launcher is available in the virtual display. @@ -63,15 +61,3 @@ To move them to the main display instead, use: ``` scrcpy --new-display --no-vd-destroy-content ``` - - -## Display IME policy - -By default, the virtual display IME appears on the default display. - -To make it appear on the local display, use `--display-ime-policy=local`: - -```bash -scrcpy --display-id=1 --display-ime-policy=local -scrcpy --new-display --display-ime-policy=local -``` diff --git a/doc/windows.md b/doc/windows.md index fb3e3887..ec7b904b 100644 --- a/doc/windows.md +++ b/doc/windows.md @@ -6,26 +6,20 @@ Download the [latest release]: - - [`scrcpy-win64-v3.2.zip`][direct-win64] (64-bit) - SHA-256: `eaa27133e0520979873ba57ad651560a4cc2618373bd05450b23a84d32beafd0` - - [`scrcpy-win32-v3.2.zip`][direct-win32] (32-bit) - SHA-256: `4a3407d7f0c2c8a03e22a12cf0b5e1e585a5056fe23c8e5cf3252207c6fa8357` + - [`scrcpy-win64-v3.1.zip`][direct-win64] (64-bit) + SHA-256: `0c05ea395d95cfe36bee974eeb435a3db87ea5594ff738370d5dc3068a9538ca` + - [`scrcpy-win32-v3.1.zip`][direct-win32] (32-bit) + SHA-256: `2b4674ef76719680ac5a9b482d1943bdde3fa25821ad2e98f3c40c347d00d560` [latest release]: https://github.com/Genymobile/scrcpy/releases/latest -[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v3.2/scrcpy-win64-v3.2.zip -[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v3.2/scrcpy-win32-v3.2.zip +[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-win64-v3.1.zip +[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-win32-v3.1.zip and extract it. ### From a package manager -From [WinGet] (ADB and other dependencies will be installed alongside scrcpy): - -```bash -winget install --exact Genymobile.scrcpy -``` - From [Chocolatey]: ```bash @@ -35,12 +29,12 @@ choco install adb # if you don't have it yet From [Scoop]: + ```bash scoop install scrcpy scoop install adb # if you don't have it yet ``` -[WinGet]: https://github.com/microsoft/winget-cli [Chocolatey]: https://chocolatey.org/ [Scoop]: https://scoop.sh diff --git a/install_release.sh b/install_release.sh index 2d2d2c2f..3774be86 100755 --- a/install_release.sh +++ b/install_release.sh @@ -2,8 +2,8 @@ set -e BUILDDIR=build-auto -PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v3.2/scrcpy-server-v3.2 -PREBUILT_SERVER_SHA256=b920e0ea01936bf2482f4ba2fa985c22c13c621999e3d33b45baa5acfc1ea3d0 +PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v3.1/scrcpy-server-v3.1 +PREBUILT_SERVER_SHA256=958f0944a62f23b1f33a16e9eb14844c1a04b882ca175a738c16d23cb22b86c0 echo "[scrcpy] Downloading prebuilt server..." wget "$PREBUILT_SERVER_URL" -O scrcpy-server diff --git a/meson.build b/meson.build index b64a6c90..aa1a3a3b 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('scrcpy', 'c', - version: '3.2', - meson_version: '>= 0.49', + version: '3.1', + meson_version: '>= 0.48', default_options: [ 'c_std=c11', 'warning_level=2', diff --git a/server/build.gradle b/server/build.gradle index 02508001..9c0543e9 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -7,8 +7,8 @@ android { applicationId "com.genymobile.scrcpy" minSdkVersion 21 targetSdkVersion 35 - versionCode 30200 - versionName "3.2" + versionCode 30100 + versionName "3.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/server/build_without_gradle.sh b/server/build_without_gradle.sh index 8bb8632b..d16592b4 100755 --- a/server/build_without_gradle.sh +++ b/server/build_without_gradle.sh @@ -12,7 +12,7 @@ set -e SCRCPY_DEBUG=false -SCRCPY_VERSION_NAME=3.2 +SCRCPY_VERSION_NAME=3.1 PLATFORM=${ANDROID_PLATFORM:-35} BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-35.0.0} @@ -47,8 +47,10 @@ EOF echo "Generating java from aidl..." cd "$SERVER_DIR/src/main/aidl" +"$BUILD_TOOLS_DIR/aidl" -o"$GEN_DIR" -I. android/view/IRotationWatcher.aidl "$BUILD_TOOLS_DIR/aidl" -o"$GEN_DIR" -I. \ android/content/IOnPrimaryClipChangedListener.aidl +"$BUILD_TOOLS_DIR/aidl" -o"$GEN_DIR" -I. android/view/IDisplayFoldListener.aidl "$BUILD_TOOLS_DIR/aidl" -o"$GEN_DIR" -I. -p "$ANDROID_AIDL" \ android/view/IDisplayWindowListener.aidl diff --git a/server/meson.build b/server/meson.build index 55828e2d..42b97981 100644 --- a/server/meson.build +++ b/server/meson.build @@ -23,9 +23,3 @@ else install: true, install_dir: 'share/scrcpy') endif - -if meson.version().version_compare('>= 0.58.0') - devenv = environment() - devenv.set('SCRCPY_SERVER_PATH', meson.current_build_dir() / 'scrcpy-server') - meson.add_devenv(devenv) -endif diff --git a/server/src/main/aidl/android/view/IDisplayFoldListener.aidl b/server/src/main/aidl/android/view/IDisplayFoldListener.aidl new file mode 100644 index 00000000..2c91149d --- /dev/null +++ b/server/src/main/aidl/android/view/IDisplayFoldListener.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +/** + * {@hide} + */ +oneway interface IDisplayFoldListener +{ + /** Called when the foldedness of a display changes */ + void onDisplayFoldChanged(int displayId, boolean folded); +} diff --git a/server/src/main/aidl/android/view/IRotationWatcher.aidl b/server/src/main/aidl/android/view/IRotationWatcher.aidl new file mode 100644 index 00000000..2cc5e44a --- /dev/null +++ b/server/src/main/aidl/android/view/IRotationWatcher.aidl @@ -0,0 +1,25 @@ +/* //device/java/android/android/hardware/ISensorListener.aidl +** +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.view; + +/** + * {@hide} + */ +interface IRotationWatcher { + oneway void onRotationChanged(int rotation); +} diff --git a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java index 51db985c..49b23e81 100644 --- a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java +++ b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java @@ -4,7 +4,6 @@ import com.genymobile.scrcpy.device.Device; import com.genymobile.scrcpy.util.Ln; import com.genymobile.scrcpy.util.Settings; import com.genymobile.scrcpy.util.SettingsException; -import com.genymobile.scrcpy.wrappers.ServiceManager; import android.os.BatteryManager; import android.system.ErrnoException; @@ -98,31 +97,18 @@ public final class CleanUp { } } + boolean powerOffScreen = options.getPowerOffScreenOnClose(); int displayId = options.getDisplayId(); - int restoreDisplayImePolicy = -1; - if (displayId > 0) { - int displayImePolicy = options.getDisplayImePolicy(); - if (displayImePolicy != -1) { - int currentDisplayImePolicy = ServiceManager.getWindowManager().getDisplayImePolicy(displayId); - if (currentDisplayImePolicy != displayImePolicy) { - ServiceManager.getWindowManager().setDisplayImePolicy(displayId, displayImePolicy); - restoreDisplayImePolicy = currentDisplayImePolicy; - } - } - } - - boolean powerOffScreen = options.getPowerOffScreenOnClose(); - try { - run(displayId, restoreStayOn, disableShowTouches, powerOffScreen, restoreScreenOffTimeout, restoreDisplayImePolicy); + run(displayId, restoreStayOn, disableShowTouches, powerOffScreen, restoreScreenOffTimeout); } catch (IOException e) { Ln.e("Clean up I/O exception", e); } } - private void run(int displayId, int restoreStayOn, boolean disableShowTouches, boolean powerOffScreen, int restoreScreenOffTimeout, - int restoreDisplayImePolicy) throws IOException { + private void run(int displayId, int restoreStayOn, boolean disableShowTouches, boolean powerOffScreen, int restoreScreenOffTimeout) + throws IOException { String[] cmd = { "app_process", "/", @@ -132,7 +118,6 @@ public final class CleanUp { String.valueOf(disableShowTouches), String.valueOf(powerOffScreen), String.valueOf(restoreScreenOffTimeout), - String.valueOf(restoreDisplayImePolicy), }; ProcessBuilder builder = new ProcessBuilder(cmd); @@ -193,7 +178,6 @@ public final class CleanUp { boolean disableShowTouches = Boolean.parseBoolean(args[2]); boolean powerOffScreen = Boolean.parseBoolean(args[3]); int restoreScreenOffTimeout = Integer.parseInt(args[4]); - int restoreDisplayImePolicy = Integer.parseInt(args[5]); // Dynamic option boolean restoreDisplayPower = false; @@ -239,11 +223,6 @@ public final class CleanUp { } } - if (restoreDisplayImePolicy != -1) { - Ln.i("Restoring \"display IME policy\""); - ServiceManager.getWindowManager().setDisplayImePolicy(displayId, restoreDisplayImePolicy); - } - // Change the power of the main display when mirroring a virtual display int targetDisplayId = displayId != Device.DISPLAY_ID_NONE ? displayId : 0; if (Device.isScreenOn(targetDisplayId)) { diff --git a/server/src/main/java/com/genymobile/scrcpy/FakeContext.java b/server/src/main/java/com/genymobile/scrcpy/FakeContext.java index 22fc6d49..2b83e397 100644 --- a/server/src/main/java/com/genymobile/scrcpy/FakeContext.java +++ b/server/src/main/java/com/genymobile/scrcpy/FakeContext.java @@ -72,7 +72,7 @@ public final class FakeContext extends ContextWrapper { @Override public AttributionSource getAttributionSource() { AttributionSource.Builder builder = new AttributionSource.Builder(Process.SHELL_UID); - builder.setPackageName("shell"); + builder.setPackageName(PACKAGE_NAME); return builder.build(); } diff --git a/server/src/main/java/com/genymobile/scrcpy/Options.java b/server/src/main/java/com/genymobile/scrcpy/Options.java index 66bb68e8..8a438750 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Options.java +++ b/server/src/main/java/com/genymobile/scrcpy/Options.java @@ -12,7 +12,6 @@ import com.genymobile.scrcpy.video.CameraAspectRatio; import com.genymobile.scrcpy.video.CameraFacing; import com.genymobile.scrcpy.video.VideoCodec; import com.genymobile.scrcpy.video.VideoSource; -import com.genymobile.scrcpy.wrappers.WindowManager; import android.graphics.Rect; import android.util.Pair; @@ -49,7 +48,6 @@ public class Options { private boolean showTouches; private boolean stayAwake; private int screenOffTimeout = -1; - private int displayImePolicy = -1; private List videoCodecOptions; private List audioCodecOptions; @@ -188,10 +186,6 @@ public class Options { return screenOffTimeout; } - public int getDisplayImePolicy() { - return displayImePolicy; - } - public List getVideoCodecOptions() { return videoCodecOptions; } @@ -488,9 +482,6 @@ public class Options { options.captureOrientationLock = pair.first; options.captureOrientation = pair.second; break; - case "display_ime_policy": - options.displayImePolicy = parseDisplayImePolicy(value); - break; case "send_device_meta": options.sendDeviceMeta = Boolean.parseBoolean(value); break; @@ -635,17 +626,4 @@ public class Options { return Pair.create(lock, Orientation.getByName(value)); } - - private static int parseDisplayImePolicy(String value) { - switch (value) { - case "local": - return WindowManager.DISPLAY_IME_POLICY_LOCAL; - case "fallback": - return WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; - case "hide": - return WindowManager.DISPLAY_IME_POLICY_HIDE; - default: - throw new IllegalArgumentException("Invalid display IME policy: " + value); - } - } } diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index 09cfd6cf..eb8b533a 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -80,15 +80,9 @@ public final class Server { throw new ConfigurationException("Camera mirroring is not supported"); } - if (Build.VERSION.SDK_INT < AndroidVersions.API_29_ANDROID_10) { - if (options.getNewDisplay() != null) { - Ln.e("New virtual display is not supported before Android 10"); - throw new ConfigurationException("New virtual display is not supported"); - } - if (options.getDisplayImePolicy() != -1) { - Ln.e("Display IME policy is not supported before Android 10"); - throw new ConfigurationException("Display IME policy is not supported"); - } + if (Build.VERSION.SDK_INT < AndroidVersions.API_29_ANDROID_10 && options.getNewDisplay() != null) { + Ln.e("New virtual display is not supported before Android 10"); + throw new ConfigurationException("New virtual display is not supported"); } CleanUp cleanUp = null; diff --git a/server/src/main/java/com/genymobile/scrcpy/Workarounds.java b/server/src/main/java/com/genymobile/scrcpy/Workarounds.java index fb4c1389..eec00a04 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Workarounds.java +++ b/server/src/main/java/com/genymobile/scrcpy/Workarounds.java @@ -42,11 +42,6 @@ public final class Workarounds { Field sCurrentActivityThreadField = ACTIVITY_THREAD_CLASS.getDeclaredField("sCurrentActivityThread"); sCurrentActivityThreadField.setAccessible(true); sCurrentActivityThreadField.set(null, ACTIVITY_THREAD); - - // activityThread.mSystemThread = true; - Field mSystemThreadField = ACTIVITY_THREAD_CLASS.getDeclaredField("mSystemThread"); - mSystemThreadField.setAccessible(true); - mSystemThreadField.setBoolean(ACTIVITY_THREAD, true); } catch (Exception e) { throw new AssertionError(e); } @@ -137,13 +132,10 @@ public final class Workarounds { try { Class configurationControllerClass = Class.forName("android.app.ConfigurationController"); Class activityThreadInternalClass = Class.forName("android.app.ActivityThreadInternal"); - - // configurationController = new ConfigurationController(ACTIVITY_THREAD); Constructor configurationControllerConstructor = configurationControllerClass.getDeclaredConstructor(activityThreadInternalClass); configurationControllerConstructor.setAccessible(true); Object configurationController = configurationControllerConstructor.newInstance(ACTIVITY_THREAD); - // ACTIVITY_THREAD.mConfigurationController = configurationController; Field configurationControllerField = ACTIVITY_THREAD_CLASS.getDeclaredField("mConfigurationController"); configurationControllerField.setAccessible(true); configurationControllerField.set(ACTIVITY_THREAD, configurationController); diff --git a/server/src/main/java/com/genymobile/scrcpy/audio/AudioDirectCapture.java b/server/src/main/java/com/genymobile/scrcpy/audio/AudioDirectCapture.java index bf870bee..5c859738 100644 --- a/server/src/main/java/com/genymobile/scrcpy/audio/AudioDirectCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/audio/AudioDirectCapture.java @@ -12,6 +12,7 @@ import android.content.ComponentName; import android.content.Intent; import android.media.AudioRecord; import android.media.MediaCodec; +import android.media.MediaRecorder; import android.os.Build; import android.os.SystemClock; @@ -31,7 +32,18 @@ public class AudioDirectCapture implements AudioCapture { private AudioRecordReader reader; public AudioDirectCapture(AudioSource audioSource) { - this.audioSource = audioSource.getDirectAudioSource(); + this.audioSource = getAudioSourceValue(audioSource); + } + + private static int getAudioSourceValue(AudioSource audioSource) { + switch (audioSource) { + case OUTPUT: + return MediaRecorder.AudioSource.REMOTE_SUBMIX; + case MIC: + return MediaRecorder.AudioSource.MIC; + default: + throw new IllegalArgumentException("Unsupported audio source: " + audioSource); + } } @TargetApi(AndroidVersions.API_23_ANDROID_6_0) diff --git a/server/src/main/java/com/genymobile/scrcpy/audio/AudioEncoder.java b/server/src/main/java/com/genymobile/scrcpy/audio/AudioEncoder.java index 33177228..267be60a 100644 --- a/server/src/main/java/com/genymobile/scrcpy/audio/AudioEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/audio/AudioEncoder.java @@ -55,9 +55,6 @@ public final class AudioEncoder implements AsyncProcessor { private final List codecOptions; private final String encoderName; - private boolean recreatePts; - private long previousPts; - // Capacity of 64 is in practice "infinite" (it is limited by the number of available MediaCodec buffers, typically 4). // So many pending tasks would lead to an unacceptable delay anyway. private final BlockingQueue inputTasks = new ArrayBlockingQueue<>(64); @@ -121,9 +118,6 @@ public final class AudioEncoder implements AsyncProcessor { OutputTask task = outputTasks.take(); ByteBuffer buffer = mediaCodec.getOutputBuffer(task.index); try { - if (recreatePts) { - fixTimestamp(task.bufferInfo); - } streamer.writePacket(buffer, task.bufferInfo); } finally { mediaCodec.releaseOutputBuffer(task.index, false); @@ -131,25 +125,6 @@ public final class AudioEncoder implements AsyncProcessor { } } - private void fixTimestamp(MediaCodec.BufferInfo bufferInfo) { - assert recreatePts; - - if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { - // Config packet, nothing to fix - return; - } - - long pts = bufferInfo.presentationTimeUs; - if (previousPts != 0) { - long now = System.nanoTime() / 1000; - // This specific encoder produces PTS matching the exact number of samples - long duration = pts - previousPts; - bufferInfo.presentationTimeUs = now - duration; - } - - previousPts = pts; - } - @Override public void start(TerminationListener listener) { thread = new Thread(() -> { @@ -219,12 +194,6 @@ public final class AudioEncoder implements AsyncProcessor { Codec codec = streamer.getCodec(); mediaCodec = createMediaCodec(codec, encoderName); - // The default OPUS and FLAC encoders overwrite the input PTS with a value that matches the number of samples. This is not the behavior - // we want: it ignores any audio clock drift and hard silences (packets not produced on silence). To work around this behavior, - // regenerate PTS based on the current time and the packet duration. - String codecName = mediaCodec.getCanonicalName(); - recreatePts = "c2.android.opus.encoder".equals(codecName) || "c2.android.flac.encoder".equals(codecName); - mediaCodecThread = new HandlerThread("media-codec"); mediaCodecThread.start(); diff --git a/server/src/main/java/com/genymobile/scrcpy/audio/AudioSource.java b/server/src/main/java/com/genymobile/scrcpy/audio/AudioSource.java index d16b5e38..6082f20e 100644 --- a/server/src/main/java/com/genymobile/scrcpy/audio/AudioSource.java +++ b/server/src/main/java/com/genymobile/scrcpy/audio/AudioSource.java @@ -1,38 +1,20 @@ package com.genymobile.scrcpy.audio; -import android.annotation.SuppressLint; -import android.media.MediaRecorder; - -@SuppressLint("InlinedApi") public enum AudioSource { - OUTPUT("output", MediaRecorder.AudioSource.REMOTE_SUBMIX), - MIC("mic", MediaRecorder.AudioSource.MIC), - PLAYBACK("playback", -1), - MIC_UNPROCESSED("mic-unprocessed", MediaRecorder.AudioSource.UNPROCESSED), - MIC_CAMCORDER("mic-camcorder", MediaRecorder.AudioSource.CAMCORDER), - MIC_VOICE_RECOGNITION("mic-voice-recognition", MediaRecorder.AudioSource.VOICE_RECOGNITION), - MIC_VOICE_COMMUNICATION("mic-voice-communication", MediaRecorder.AudioSource.VOICE_COMMUNICATION), - VOICE_CALL("voice-call", MediaRecorder.AudioSource.VOICE_CALL), - VOICE_CALL_UPLINK("voice-call-uplink", MediaRecorder.AudioSource.VOICE_UPLINK), - VOICE_CALL_DOWNLINK("voice-call-downlink", MediaRecorder.AudioSource.VOICE_DOWNLINK), - VOICE_PERFORMANCE("voice-performance", MediaRecorder.AudioSource.VOICE_PERFORMANCE); + OUTPUT("output"), + MIC("mic"), + PLAYBACK("playback"); private final String name; - private final int directAudioSource; - AudioSource(String name, int directAudioSource) { + AudioSource(String name) { this.name = name; - this.directAudioSource = directAudioSource; } public boolean isDirect() { return this != PLAYBACK; } - public int getDirectAudioSource() { - return directAudioSource; - } - public static AudioSource findByName(String name) { for (AudioSource audioSource : AudioSource.values()) { if (name.equals(audioSource.name)) { diff --git a/server/src/main/java/com/genymobile/scrcpy/util/LogUtils.java b/server/src/main/java/com/genymobile/scrcpy/util/LogUtils.java index 4f8927ec..088be7e7 100644 --- a/server/src/main/java/com/genymobile/scrcpy/util/LogUtils.java +++ b/server/src/main/java/com/genymobile/scrcpy/util/LogUtils.java @@ -120,39 +120,17 @@ public final class LogUtils { } } - private static boolean isCameraBackwardCompatible(CameraCharacteristics characteristics) { - int[] capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); - if (capabilities == null) { - return false; - } - - for (int capability : capabilities) { - if (capability == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) { - return true; - } - } - - return false; - } - public static String buildCameraListMessage(boolean includeSizes) { StringBuilder builder = new StringBuilder("List of cameras:"); CameraManager cameraManager = ServiceManager.getCameraManager(); try { String[] cameraIds = cameraManager.getCameraIdList(); - if (cameraIds.length == 0) { + if (cameraIds == null || cameraIds.length == 0) { builder.append("\n (none)"); } else { for (String id : cameraIds) { - CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); - - if (!isCameraBackwardCompatible(characteristics)) { - // Ignore depth cameras as suggested by official documentation - // - continue; - } - builder.append("\n --camera-id=").append(id); + CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); int facing = characteristics.get(CameraCharacteristics.LENS_FACING); builder.append(" (").append(getCameraFacingName(facing)).append(", "); @@ -163,10 +141,8 @@ public final class LogUtils { try { // Capture frame rates for low-FPS mode are the same for every resolution Range[] lowFpsRanges = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); - if (lowFpsRanges != null) { - SortedSet uniqueLowFps = getUniqueSet(lowFpsRanges); - builder.append(", fps=").append(uniqueLowFps); - } + SortedSet uniqueLowFps = getUniqueSet(lowFpsRanges); + builder.append(", fps=").append(uniqueLowFps); } catch (Exception e) { // Some devices may provide invalid ranges, causing an IllegalArgumentException "lower must be less than or equal to upper" Ln.w("Could not get available frame rates for camera " + id, e); diff --git a/server/src/main/java/com/genymobile/scrcpy/video/DisplaySizeMonitor.java b/server/src/main/java/com/genymobile/scrcpy/video/DisplaySizeMonitor.java index 3d7cccfe..ff863aa8 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/DisplaySizeMonitor.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/DisplaySizeMonitor.java @@ -23,9 +23,7 @@ public class DisplaySizeMonitor { // On Android 14, DisplayListener may be broken (it never sends events). This is fixed in recent Android 14 upgrades, but we can't really // detect it directly, so register a DisplayWindowListener (introduced in Android 11) to listen to configuration changes instead. - // It has been broken again after an Android 15 upgrade: - // So use the default method only before Android 14. - private static final boolean USE_DEFAULT_METHOD = Build.VERSION.SDK_INT < AndroidVersions.API_34_ANDROID_14; + private static final boolean USE_DEFAULT_METHOD = Build.VERSION.SDK_INT != AndroidVersions.API_34_ANDROID_14; private DisplayManager.DisplayListenerHandle displayListenerHandle; private HandlerThread handlerThread; diff --git a/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java b/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java index 792b3a8a..033d6b9a 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java @@ -49,7 +49,6 @@ public class NewDisplayCapture extends SurfaceCapture { private Size mainDisplaySize; private int mainDisplayDpi; private int maxSize; - private int displayImePolicy; private final Rect crop; private final boolean captureOrientationLocked; private final Orientation captureOrientation; @@ -69,7 +68,6 @@ public class NewDisplayCapture extends SurfaceCapture { this.newDisplay = options.getNewDisplay(); assert newDisplay != null; this.maxSize = options.getMaxSize(); - this.displayImePolicy = options.getDisplayImePolicy(); this.crop = options.getCrop(); assert options.getCaptureOrientationLock() != null; this.captureOrientationLocked = options.getCaptureOrientationLock() != Orientation.Lock.Unlocked; @@ -193,10 +191,6 @@ public class NewDisplayCapture extends SurfaceCapture { virtualDisplayId = virtualDisplay.getDisplay().getDisplayId(); Ln.i("New display: " + displaySize.getWidth() + "x" + displaySize.getHeight() + "/" + dpi + " (id=" + virtualDisplayId + ")"); - if (displayImePolicy != -1) { - ServiceManager.getWindowManager().setDisplayImePolicy(virtualDisplayId, displayImePolicy); - } - displaySizeMonitor.start(virtualDisplayId, this::invalidate); } catch (Exception e) { Ln.e("Could not create display", e); diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/WindowManager.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/WindowManager.java index 7ba5cc06..86dd83f2 100644 --- a/server/src/main/java/com/genymobile/scrcpy/wrappers/WindowManager.java +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/WindowManager.java @@ -4,20 +4,14 @@ import com.genymobile.scrcpy.AndroidVersions; import com.genymobile.scrcpy.util.Ln; import android.annotation.TargetApi; -import android.os.Build; import android.os.IInterface; +import android.view.IDisplayFoldListener; import android.view.IDisplayWindowListener; +import android.view.IRotationWatcher; import java.lang.reflect.Method; public final class WindowManager { - - @SuppressWarnings("checkstyle:LineLength") - // - public static final int DISPLAY_IME_POLICY_LOCAL = 0; - public static final int DISPLAY_IME_POLICY_FALLBACK_DISPLAY = 1; - public static final int DISPLAY_IME_POLICY_HIDE = 2; - private final IInterface manager; private Method getRotationMethod; @@ -30,9 +24,6 @@ public final class WindowManager { private Method thawDisplayRotationMethod; private int thawDisplayRotationMethodVersion; - private Method getDisplayImePolicyMethod; - private Method setDisplayImePolicyMethod; - static WindowManager create() { IInterface manager = ServiceManager.getService("window", "android.view.IWindowManager"); return new WindowManager(manager); @@ -191,6 +182,52 @@ public final class WindowManager { } } + public void registerRotationWatcher(IRotationWatcher rotationWatcher, int displayId) { + try { + Class cls = manager.getClass(); + try { + // display parameter added since this commit: + // https://android.googlesource.com/platform/frameworks/base/+/35fa3c26adcb5f6577849fd0df5228b1f67cf2c6%5E%21/#F1 + cls.getMethod("watchRotation", IRotationWatcher.class, int.class).invoke(manager, rotationWatcher, displayId); + } catch (NoSuchMethodException e) { + // old version + if (displayId != 0) { + Ln.e("Secondary display rotation not supported on this device"); + return; + } + cls.getMethod("watchRotation", IRotationWatcher.class).invoke(manager, rotationWatcher); + } + } catch (Exception e) { + Ln.e("Could not register rotation watcher", e); + } + } + + public void unregisterRotationWatcher(IRotationWatcher rotationWatcher) { + try { + manager.getClass().getMethod("removeRotationWatcher", IRotationWatcher.class).invoke(manager, rotationWatcher); + } catch (Exception e) { + Ln.e("Could not unregister rotation watcher", e); + } + } + + @TargetApi(AndroidVersions.API_29_ANDROID_10) + public void registerDisplayFoldListener(IDisplayFoldListener foldListener) { + try { + manager.getClass().getMethod("registerDisplayFoldListener", IDisplayFoldListener.class).invoke(manager, foldListener); + } catch (Exception e) { + Ln.e("Could not register display fold listener", e); + } + } + + @TargetApi(AndroidVersions.API_29_ANDROID_10) + public void unregisterDisplayFoldListener(IDisplayFoldListener foldListener) { + try { + manager.getClass().getMethod("unregisterDisplayFoldListener", IDisplayFoldListener.class).invoke(manager, foldListener); + } catch (Exception e) { + Ln.e("Could not unregister display fold listener", e); + } + } + @TargetApi(AndroidVersions.API_30_ANDROID_11) public int[] registerDisplayWindowListener(IDisplayWindowListener listener) { try { @@ -209,59 +246,4 @@ public final class WindowManager { Ln.e("Could not unregister display window listener", e); } } - - @TargetApi(AndroidVersions.API_29_ANDROID_10) - private Method getGetDisplayImePolicyMethod() throws NoSuchMethodException { - if (getDisplayImePolicyMethod == null) { - if (Build.VERSION.SDK_INT >= AndroidVersions.API_31_ANDROID_12) { - getDisplayImePolicyMethod = manager.getClass().getMethod("getDisplayImePolicy", int.class); - } else { - getDisplayImePolicyMethod = manager.getClass().getMethod("shouldShowIme", int.class); - } - } - return getDisplayImePolicyMethod; - } - - @TargetApi(AndroidVersions.API_29_ANDROID_10) - public int getDisplayImePolicy(int displayId) { - try { - Method method = getGetDisplayImePolicyMethod(); - if (Build.VERSION.SDK_INT >= AndroidVersions.API_31_ANDROID_12) { - return (int) method.invoke(manager, displayId); - } - boolean shouldShowIme = (boolean) method.invoke(manager, displayId); - return shouldShowIme ? DISPLAY_IME_POLICY_LOCAL : DISPLAY_IME_POLICY_FALLBACK_DISPLAY; - } catch (ReflectiveOperationException e) { - Ln.e("Could not invoke method", e); - return -1; - } - } - - @TargetApi(AndroidVersions.API_29_ANDROID_10) - private Method getSetDisplayImePolicyMethod() throws NoSuchMethodException { - if (setDisplayImePolicyMethod == null) { - if (Build.VERSION.SDK_INT >= AndroidVersions.API_31_ANDROID_12) { - setDisplayImePolicyMethod = manager.getClass().getMethod("setDisplayImePolicy", int.class, int.class); - } else { - setDisplayImePolicyMethod = manager.getClass().getMethod("setShouldShowIme", int.class, boolean.class); - } - } - return setDisplayImePolicyMethod; - } - - @TargetApi(AndroidVersions.API_29_ANDROID_10) - public void setDisplayImePolicy(int displayId, int displayImePolicy) { - try { - Method method = getSetDisplayImePolicyMethod(); - if (Build.VERSION.SDK_INT >= AndroidVersions.API_31_ANDROID_12) { - method.invoke(manager, displayId, displayImePolicy); - } else if (displayImePolicy != DISPLAY_IME_POLICY_HIDE) { - method.invoke(manager, displayId, displayImePolicy == DISPLAY_IME_POLICY_LOCAL); - } else { - Ln.w("DISPLAY_IME_POLICY_HIDE is not supported before Android 12"); - } - } catch (ReflectiveOperationException e) { - Ln.e("Could not invoke method", e); - } - } }