diff --git a/FAQ.md b/FAQ.md index 64002940..76f572ce 100644 --- a/FAQ.md +++ b/FAQ.md @@ -24,20 +24,6 @@ If you still encounter problems, please see [issue 9]. [issue 9]: https://github.com/Genymobile/scrcpy/issues/9 -### I get a black screen for some applications like Silence - -This is expected, they requested to [protect] the screen. - -In [Silence], you can disable it in settings → Privacy → Screen security. - -[protect]: https://developer.android.com/reference/android/view/Display#FLAG_SECURE -[silence]: https://f-droid.org/en/packages/org.smssecure.smssecure/ - -See [issue 36]. - -[issue 36]: https://github.com/Genymobile/scrcpy/issues/36 - - ### Mouse clicks do not work On some devices, you may need to enable an option to allow [simulating input]. diff --git a/Makefile.CrossWindows b/Makefile.CrossWindows index 45aad4c3..99a35cab 100644 --- a/Makefile.CrossWindows +++ b/Makefile.CrossWindows @@ -100,10 +100,10 @@ dist-win32: build-server build-win32 build-win32-noconsole cp "$(SERVER_BUILD_DIR)"/server/scrcpy-server.jar "$(DIST)/$(WIN32_TARGET_DIR)/" cp "$(WIN32_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN32_TARGET_DIR)/" cp "$(WIN32_NOCONSOLE_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN32_TARGET_DIR)/scrcpy-noconsole.exe" - cp prebuilt-deps/ffmpeg-4.0.2-win32-shared/bin/avutil-56.dll "$(DIST)/$(WIN32_TARGET_DIR)/" - cp prebuilt-deps/ffmpeg-4.0.2-win32-shared/bin/avcodec-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/" - cp prebuilt-deps/ffmpeg-4.0.2-win32-shared/bin/avformat-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/" - cp prebuilt-deps/ffmpeg-4.0.2-win32-shared/bin/swresample-3.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.1-win32-shared/bin/avutil-56.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.1-win32-shared/bin/avcodec-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.1-win32-shared/bin/avformat-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.1-win32-shared/bin/swresample-3.dll "$(DIST)/$(WIN32_TARGET_DIR)/" cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN32_TARGET_DIR)/" cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/" cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/" @@ -114,10 +114,10 @@ dist-win64: build-server build-win64 build-win64-noconsole cp "$(SERVER_BUILD_DIR)"/server/scrcpy-server.jar "$(DIST)/$(WIN64_TARGET_DIR)/" cp "$(WIN64_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN64_TARGET_DIR)/" cp "$(WIN64_NOCONSOLE_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN64_TARGET_DIR)/scrcpy-noconsole.exe" - cp prebuilt-deps/ffmpeg-4.0.2-win64-shared/bin/avutil-56.dll "$(DIST)/$(WIN64_TARGET_DIR)/" - cp prebuilt-deps/ffmpeg-4.0.2-win64-shared/bin/avcodec-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/" - cp prebuilt-deps/ffmpeg-4.0.2-win64-shared/bin/avformat-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/" - cp prebuilt-deps/ffmpeg-4.0.2-win64-shared/bin/swresample-3.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.1-win64-shared/bin/avutil-56.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.1-win64-shared/bin/avcodec-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.1-win64-shared/bin/avformat-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.1-win64-shared/bin/swresample-3.dll "$(DIST)/$(WIN64_TARGET_DIR)/" cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN64_TARGET_DIR)/" cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/" cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/" diff --git a/app/src/command.c b/app/src/command.c index b5bb9572..b8340ecc 100644 --- a/app/src/command.c +++ b/app/src/command.c @@ -135,11 +135,6 @@ process_t adb_install(const char *serial, const char *local) { return proc; } -process_t adb_remove_path(const char *serial, const char *path) { - const char *const adb_cmd[] = {"shell", "rm", path}; - return adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd)); -} - SDL_bool process_check_success(process_t proc, const char *name) { if (proc == PROCESS_NONE) { LOGE("Could not execute \"%s\"", name); diff --git a/app/src/command.h b/app/src/command.h index 3e0fcca6..98b3a881 100644 --- a/app/src/command.h +++ b/app/src/command.h @@ -49,7 +49,6 @@ process_t adb_reverse(const char *serial, const char *device_socket_name, uint16 process_t adb_reverse_remove(const char *serial, const char *device_socket_name); process_t adb_push(const char *serial, const char *local, const char *remote); process_t adb_install(const char *serial, const char *local); -process_t adb_remove_path(const char *serial, const char *path); // convenience function to wait for a successful process execution // automatically log process errors with the provided process name diff --git a/app/src/common.h b/app/src/common.h index 9f5f9c6e..d3d000f9 100644 --- a/app/src/common.h +++ b/app/src/common.h @@ -13,8 +13,8 @@ struct size { }; struct point { - Uint16 x; - Uint16 y; + Sint32 x; + Sint32 y; }; struct position { diff --git a/app/src/control_event.c b/app/src/control_event.c index ace78dbf..34b71fb0 100644 --- a/app/src/control_event.c +++ b/app/src/control_event.c @@ -8,10 +8,10 @@ #include "log.h" static void write_position(Uint8 *buf, const struct position *position) { - buffer_write16be(&buf[0], position->point.x); - buffer_write16be(&buf[2], position->point.y); - buffer_write16be(&buf[4], position->screen_size.width); - buffer_write16be(&buf[6], position->screen_size.height); + buffer_write32be(&buf[0], position->point.x); + buffer_write32be(&buf[4], position->point.y); + buffer_write16be(&buf[8], position->screen_size.width); + buffer_write16be(&buf[10], position->screen_size.height); } int control_event_serialize(const struct control_event *event, unsigned char *buf) { @@ -37,12 +37,12 @@ int control_event_serialize(const struct control_event *event, unsigned char *bu buf[1] = event->mouse_event.action; buffer_write32be(&buf[2], event->mouse_event.buttons); write_position(&buf[6], &event->mouse_event.position); - return 14; + return 18; case CONTROL_EVENT_TYPE_SCROLL: write_position(&buf[1], &event->scroll_event.position); - buffer_write32be(&buf[9], (Uint32) event->scroll_event.hscroll); - buffer_write32be(&buf[13], (Uint32) event->scroll_event.vscroll); - return 17; + buffer_write32be(&buf[13], (Uint32) event->scroll_event.hscroll); + buffer_write32be(&buf[17], (Uint32) event->scroll_event.vscroll); + return 21; case CONTROL_EVENT_TYPE_COMMAND: buf[1] = event->command_event.action; return 2; diff --git a/app/src/input_manager.c b/app/src/input_manager.c index 7a3a4ad1..7099249e 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -18,9 +18,15 @@ static void convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int *y = (int) (*y / scale_y) - viewport.y; } -static void get_mouse_point(struct screen *screen, int *x, int *y) { - SDL_GetMouseState(x, y); - convert_to_renderer_coordinates(screen->renderer, x, y); +static struct point get_mouse_point(struct screen *screen) { + int x; + int y; + SDL_GetMouseState(&x, &y); + convert_to_renderer_coordinates(screen->renderer, &x, &y); + return (struct point) { + .x = x, + .y = y, + }; } static const int ACTION_DOWN = 1; @@ -273,9 +279,6 @@ static SDL_bool is_outside_device_screen(struct input_manager *input_manager, void input_manager_process_mouse_button(struct input_manager *input_manager, const SDL_MouseButtonEvent *event) { - SDL_bool outside_device_screen = is_outside_device_screen(input_manager, - event->x, - event->y); if (event->type == SDL_MOUSEBUTTONDOWN) { if (event->button == SDL_BUTTON_RIGHT) { press_back_or_turn_screen_on(input_manager->controller); @@ -286,19 +289,18 @@ void input_manager_process_mouse_button(struct input_manager *input_manager, return; } // double-click on black borders resize to fit the device screen - if (event->button == SDL_BUTTON_LEFT && event->clicks == 2 - && outside_device_screen) { - screen_resize_to_fit(input_manager->screen); - return; + if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) { + SDL_bool outside= is_outside_device_screen(input_manager, + event->x, + event->y); + if (outside) { + screen_resize_to_fit(input_manager->screen); + return; + } } // otherwise, send the click event to the device } - if (outside_device_screen) { - // ignore - return; - } - struct control_event control_event; if (mouse_button_from_sdl_to_android(event, input_manager->screen->frame_size, &control_event)) { if (!controller_push_event(input_manager->controller, &control_event)) { @@ -309,22 +311,9 @@ void input_manager_process_mouse_button(struct input_manager *input_manager, void input_manager_process_mouse_wheel(struct input_manager *input_manager, const SDL_MouseWheelEvent *event) { - int x; - int y; - get_mouse_point(input_manager->screen, &x, &y); - if (is_outside_device_screen(input_manager, x, y)) { - // ignore - return; - } - - SDL_assert_release(x >= 0 && x < 0x10000 && y >= 0 && y < 0x10000); - struct position position = { .screen_size = input_manager->screen->frame_size, - .point = { - .x = (Uint16) x, - .y = (Uint16) y, - }, + .point = get_mouse_point(input_manager->screen), }; struct control_event control_event; if (mouse_wheel_from_sdl_to_android(event, position, &control_event)) { diff --git a/app/src/screen.c b/app/src/screen.c index 5d7a4009..703def32 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -30,6 +30,9 @@ SDL_bool sdl_init_and_configure(void) { } #endif + // Do not disable the screensaver when scrcpy is running + SDL_EnableScreenSaver(); + return SDL_TRUE; } diff --git a/app/src/server.c b/app/src/server.c index 3ad21511..7835e716 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -34,11 +34,6 @@ static SDL_bool push_server(const char *serial) { return process_check_success(process, "adb push"); } -static SDL_bool remove_server(const char *serial) { - process_t process = adb_remove_path(serial, DEVICE_SERVER_PATH); - return process_check_success(process, "adb shell rm"); -} - static SDL_bool enable_tunnel_reverse(const char *serial, Uint16 local_port) { process_t process = adb_reverse(serial, SOCKET_NAME, local_port); return process_check_success(process, "adb reverse"); @@ -93,7 +88,7 @@ static process_t execute_server(const char *serial, max_size_string, bit_rate_string, tunnel_forward ? "true" : "false", - crop ? crop : "''", + crop ? crop : "-", send_frame_meta ? "true" : "false", }; return adb_execute(serial, cmd, sizeof(cmd) / sizeof(cmd[0])); @@ -167,8 +162,6 @@ SDL_bool server_start(struct server *server, const char *serial, return SDL_FALSE; } - server->server_copied_to_device = SDL_TRUE; - if (!enable_tunnel(server)) { SDL_free((void *) server->serial); return SDL_FALSE; @@ -229,10 +222,6 @@ socket_t server_connect_to(struct server *server) { close_socket(&server->server_socket); } - // the server is started, we can clean up the jar from the temporary folder - remove_server(server->serial); // ignore failure - server->server_copied_to_device = SDL_FALSE; - // we don't need the adb tunnel anymore disable_tunnel(server); // ignore failure server->tunnel_enabled = SDL_FALSE; @@ -254,10 +243,6 @@ void server_stop(struct server *server) { // ignore failure disable_tunnel(server); } - - if (server->server_copied_to_device) { - remove_server(server->serial); // ignore failure - } } void server_destroy(struct server *server) { diff --git a/app/src/server.h b/app/src/server.h index 19594c03..b9835e13 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -13,7 +13,6 @@ struct server { SDL_bool tunnel_enabled; SDL_bool tunnel_forward; // use "adb forward" instead of "adb reverse" SDL_bool send_frame_meta; // request frame PTS to be able to record properly - SDL_bool server_copied_to_device; }; #define SERVER_INITIALIZER { \ @@ -25,7 +24,6 @@ struct server { .tunnel_enabled = SDL_FALSE, \ .tunnel_forward = SDL_FALSE, \ .send_frame_meta = SDL_FALSE, \ - .server_copied_to_device = SDL_FALSE, \ } // init default values diff --git a/cross_win32.txt b/cross_win32.txt index 97ddb75f..f82056ff 100644 --- a/cross_win32.txt +++ b/cross_win32.txt @@ -15,6 +15,6 @@ cpu = 'i686' endian = 'little' [properties] -prebuilt_ffmpeg_shared = 'ffmpeg-4.0.2-win32-shared' -prebuilt_ffmpeg_dev = 'ffmpeg-4.0.2-win32-dev' +prebuilt_ffmpeg_shared = 'ffmpeg-4.1-win32-shared' +prebuilt_ffmpeg_dev = 'ffmpeg-4.1-win32-dev' prebuilt_sdl2 = 'SDL2-2.0.9/i686-w64-mingw32' diff --git a/cross_win64.txt b/cross_win64.txt index 8e5b1d1f..beca2096 100644 --- a/cross_win64.txt +++ b/cross_win64.txt @@ -15,6 +15,6 @@ cpu = 'x86_64' endian = 'little' [properties] -prebuilt_ffmpeg_shared = 'ffmpeg-4.0.2-win64-shared' -prebuilt_ffmpeg_dev = 'ffmpeg-4.0.2-win64-dev' +prebuilt_ffmpeg_shared = 'ffmpeg-4.1-win64-shared' +prebuilt_ffmpeg_dev = 'ffmpeg-4.1-win64-dev' prebuilt_sdl2 = 'SDL2-2.0.9/x86_64-w64-mingw32' diff --git a/prebuilt-deps/Makefile b/prebuilt-deps/Makefile index f00ee21e..f3c171ba 100644 --- a/prebuilt-deps/Makefile +++ b/prebuilt-deps/Makefile @@ -10,24 +10,24 @@ prepare-win32: prepare-sdl2 prepare-ffmpeg-shared-win32 prepare-ffmpeg-dev-win32 prepare-win64: prepare-sdl2 prepare-ffmpeg-shared-win64 prepare-ffmpeg-dev-win64 prepare-adb prepare-ffmpeg-shared-win32: - @./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-4.0.2-win32-shared.zip \ - cc190a3a4cf7bfbd4fbaa92609c1501a1de458055e6cfea8b745c1d515013aa8 \ - ffmpeg-4.0.2-win32-shared + @./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-4.1-win32-shared.zip \ + e692b18c01745d262c03294b382fd64df68fabe3c66aa4546a3ad3935175cde3 \ + ffmpeg-4.1-win32-shared prepare-ffmpeg-dev-win32: - @./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/dev/ffmpeg-4.0.2-win32-dev.zip \ - c72c74bad74ac0541f1b43090c26a50017c49041c182a703abd2057bb8cdc238 \ - ffmpeg-4.0.2-win32-dev + @./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/dev/ffmpeg-4.1-win32-dev.zip \ + 34bc5e471fb9160609abd6bc271e361050f3ff7376b1b8a0873cca02b38277c8 \ + ffmpeg-4.1-win32-dev prepare-ffmpeg-shared-win64: - @./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-4.0.2-win64-shared.zip \ - ede566aca8b5348dff85570f9638c6bad33209f9419f79db7bde7daa37599bff \ - ffmpeg-4.0.2-win64-shared + @./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-4.1-win64-shared.zip \ + c4908c97436c946509dc365e421159274fa4b1e66dce6fb5b63d82a6294d5357 \ + ffmpeg-4.1-win64-shared prepare-ffmpeg-dev-win64: - @./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-4.0.2-win64-dev.zip \ - 23ee994161c51285cb956b98d3caa499d48083dae7b26c1fdf77f22e98df1c5f \ - ffmpeg-4.0.2-win64-dev + @./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-4.1-win64-dev.zip \ + 761ec79aa3dae66698c9791a2f0bb9da8794246f8356cadc741ddc0eabab0471 \ + ffmpeg-4.1-win64-dev prepare-sdl2: @./prepare-dep https://libsdl.org/release/SDL2-devel-2.0.9-mingw.tar.gz \ diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java b/server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java index 83088b10..e47ca309 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlEventReader.java @@ -132,8 +132,8 @@ public class ControlEventReader { } private static Position readPosition(ByteBuffer buffer) { - int x = toUnsigned(buffer.getShort()); - int y = toUnsigned(buffer.getShort()); + int x = buffer.getInt(); + int y = buffer.getInt(); int screenWidth = toUnsigned(buffer.getShort()); int screenHeight = toUnsigned(buffer.getShort()); return new Position(x, y, screenWidth, screenHeight); diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index 0419dc52..ec63e81d 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -151,7 +151,7 @@ public class ScreenEncoder implements Device.RotationListener { } private static IBinder createDisplay() { - return SurfaceControl.createDisplay("scrcpy", false); + return SurfaceControl.createDisplay("scrcpy", true); } private static void configure(MediaCodec codec, MediaFormat format) { diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index db15fb52..fb2ba461 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -2,11 +2,14 @@ package com.genymobile.scrcpy; import android.graphics.Rect; +import java.io.File; import java.io.IOException; import java.util.Arrays; public final class Server { + private static final String SERVER_PATH = "/data/local/tmp/scrcpy-server.jar"; + private Server() { // not instantiable } @@ -46,35 +49,24 @@ public final class Server { @SuppressWarnings("checkstyle:MagicNumber") private static Options createOptions(String... args) { + if (args.length != 5) + throw new IllegalArgumentException("Expecting 5 parameters"); + Options options = new Options(); - if (args.length < 1) { - return options; - } + int maxSize = Integer.parseInt(args[0]) & ~7; // multiple of 8 options.setMaxSize(maxSize); - if (args.length < 2) { - return options; - } int bitRate = Integer.parseInt(args[1]); options.setBitRate(bitRate); - if (args.length < 3) { - return options; - } // use "adb forward" instead of "adb tunnel"? (so the server must listen) boolean tunnelForward = Boolean.parseBoolean(args[2]); options.setTunnelForward(tunnelForward); - if (args.length < 4) { - return options; - } Rect crop = parseCrop(args[3]); options.setCrop(crop); - if (args.length < 5) { - return options; - } boolean sendFrameMeta = Boolean.parseBoolean(args[4]); options.setSendFrameMeta(sendFrameMeta); @@ -82,7 +74,7 @@ public final class Server { } private static Rect parseCrop(String crop) { - if (crop.isEmpty()) { + if ("-".equals(crop)) { return null; } // input format: "width:height:x:y" @@ -97,6 +89,14 @@ public final class Server { return new Rect(x, y, x + width, y + height); } + private static void unlinkSelf() { + try { + new File(SERVER_PATH).delete(); + } catch (Exception e) { + Ln.e("Cannot unlink server", e); + } + } + public static void main(String... args) throws Exception { Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override @@ -105,6 +105,7 @@ public final class Server { } }); + unlinkSelf(); Options options = createOptions(args); scrcpy(options); }