Compare commits

..

10 Commits

Author SHA1 Message Date
Romain Vimont
100a938c80 Update issue templates 2020-04-03 18:47:16 +02:00
Romain Vimont
7bb91638ad Improve FAQ 2020-03-19 19:22:58 +01:00
Yogev Boaron Ben-Har
bc7508427b Add scoop instructions for Windows
PR #1202 <https://github.com/Genymobile/scrcpy/pull/1202>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-03-14 17:11:49 +01:00
Romain Vimont
24ade6ad77 Simplify Chocolatey documentation 2020-03-14 17:07:20 +01:00
Romain Vimont
c396758b4e Remove link to Windows 32 bits release
Binaries created with MinGW (even a simple Hello World) are detected as
malware by some anti-virus. For some reason, only the 32 bits version of
scrcpy is impacted.

Since users should use the 64 bits version by default anyway, remove the
link to the 32 bits version from the main page.

The 32 bits release is still available in the "releases" tab.

See <https://github.com/Genymobile/scrcpy/issues/1102>
2020-03-03 21:39:27 +01:00
George Stamoulis
f903cd376d Documentation rectifications
PR #1151 <https://github.com/Genymobile/scrcpy/pull/1151>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-02-16 16:04:17 +01:00
Camilo Martinez
e8127375ae Add Chocolatey for Windows install
PR #1144 <https://github.com/Genymobile/scrcpy/pull/1144>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2020-02-15 22:26:30 +01:00
Romain Vimont
1144f64214 Indicate that -s can also be used for TCP/IP 2020-02-06 18:42:08 +01:00
Romain Vimont
39356602ed Mention scrcpy Debian package in README 2020-01-19 16:19:51 +01:00
Romain Vimont
0fb22c3e98 Happy new year 2020! 2020-01-19 16:04:20 +01:00
26 changed files with 313 additions and 230 deletions

23
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,23 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
- [ ] I have read the [FAQ](https://github.com/Genymobile/scrcpy/blob/master/FAQ.md).
- [ ] I have searched in existing [issues](https://github.com/Genymobile/scrcpy/issues).
**Environment**
- OS: [e.g. Debian, Windows, macOS...]
- scrcpy version: [e.g. 1.12.1]
- installation method: [e.g. manual build, apt, snap, brew, Windows release...]
**Describe the bug**
A clear and concise description of what the bug is.
On errors, please provide the output of the console (and `adb logcat` if relevant).
Format them between code blocks (delimited by ```).
Please do not post screenshots of your terminal, just post the content as text instead.

View File

@@ -0,0 +1,22 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
- [ ] I have checked that a similar [feature request](https://github.com/Genymobile/scrcpy/issues?q=is%3Aopen+is%3Aissue+label%3A%22feature+request%22) does not already exist.
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -189,7 +189,7 @@ The client uses 4 threads:
recording,
- the **controller** thread, sending _control messages_ to the server,
- the **receiver** thread (managed by the controller), receiving _device
messages_ from the client.
messages_ from the server.
In addition, another thread can be started if necessary to handle APK
installation or file push requests (via drag&drop on the main window) or to
@@ -214,7 +214,7 @@ When a new decoded frame is available, the decoder _swaps_ the decoding and
rendering frame (with proper synchronization). Thus, it immediatly starts
to decode a new frame while the main thread renders the last one.
If a [recorder] is present (i.e. `--record` is enabled), then its muxes the raw
If a [recorder] is present (i.e. `--record` is enabled), then it muxes the raw
H.264 packet to the output video file.
[stream]: https://github.com/Genymobile/scrcpy/blob/ffe0417228fb78ab45b7ee4e202fc06fc8875bf3/app/src/stream.h

149
FAQ.md
View File

@@ -3,19 +3,102 @@
Here are the common reported problems and their status.
### On Windows, my device is not detected
## `adb` issues
The most common is your device not being detected by `adb`, or is unauthorized.
Check everything is ok by calling:
`scrcpy` execute `adb` commands to initialize the connection with the device. If
`adb` fails, then scrcpy will not work.
adb devices
In that case, it will print this error:
Windows may need some [drivers] to detect your device.
> ERROR: "adb push" returned with value 1
This is typically not a bug in _scrcpy_, but a problem in your environment.
To find out the cause, execute:
```bash
adb devices
```
### `adb` not found
You need `adb` accessible from your `PATH`.
On Windows, the current directory is in your `PATH`, and `adb.exe` is included
in the release, so it should work out-of-the-box.
### Device unauthorized
Check [stackoverflow][device-unauthorized].
[device-unauthorized]: https://stackoverflow.com/questions/23081263/adb-android-device-unauthorized
### Device not detected
If your device is not detected, you may need some [drivers] (on Windows).
[drivers]: https://developer.android.com/studio/run/oem-usb.html
### I can only mirror, I cannot interact with the device
### Several devices connected
If several devices are connected, you will encounter this error:
> adb: error: failed to get feature set: more than one device/emulator
the identifier of the device you want to mirror must be provided:
```bash
scrcpy -s 01234567890abcdef
```
Note that if your device is connected over TCP/IP, you'll get this message:
> adb: error: more than one device/emulator
> ERROR: "adb reverse" returned with value 1
> WARN: 'adb reverse' failed, fallback to 'adb forward'
This is expected (due to a bug on old Android versions, see [#5]), but in that
case, scrcpy fallbacks to a different method, which should work.
[#5]: https://github.com/Genymobile/scrcpy/issues/5
### Conflicts between adb versions
> adb server version (41) doesn't match this client (39); killing...
This error occurs when you use several `adb` versions simultaneously. You must
find the program using a different `adb` version, and use the same `adb` version
everywhere.
You could overwrite the `adb` binary in the other program, or ask _scrcpy_ to
use a specific `adb` binary, by setting the `ADB` environment variable:
```bash
set ADB=/path/to/your/adb
scrcpy
```
### Device disconnected
If _scrcpy_ stops itself with the warning "Device disconnected", then the
`adb` connection has been closed.
Try with another USB cable or plug it into another USB port. See [#281] and
[#283].
[#281]: https://github.com/Genymobile/scrcpy/issues/281
[#283]: https://github.com/Genymobile/scrcpy/issues/283
## Control issues
### Mouse and keyboard do not work
On some devices, you may need to enable an option to allow [simulating input].
In developer options, enable:
@@ -29,18 +112,25 @@ In developer options, enable:
### Mouse clicks at wrong location
On MacOS, with HiDPI support and multiple screens, input location are wrongly
scaled. See [issue 15].
scaled. See [#15].
[issue 15]: https://github.com/Genymobile/scrcpy/issues/15
[#15]: https://github.com/Genymobile/scrcpy/issues/15
A workaround is to build with HiDPI support disabled:
Open _scrcpy_ directly on the monitor you use it.
```bash
meson x --buildtype release -Dhidpi_support=false
```
However, the video will be displayed at lower resolution.
### Special characters do not work
Injecting text input is [limited to ASCII characters][text-input]. A trick
allows to also inject some [accented characters][accented-characters], but
that's all. See [#37].
[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
## Client issues
### The quality is low on HiDPI display
@@ -51,6 +141,11 @@ On Windows, you may need to configure the [scaling behavior].
[scaling behavior]: https://github.com/Genymobile/scrcpy/issues/40#issuecomment-424466723
If your computer definition is far smaller than your screen, then you'll get
poor quality. See [#40].
[#40]: https://github.com/Genymobile/scrcpy/issues/40
### KWin compositor crashes
@@ -61,19 +156,29 @@ As a workaround, [disable "Block compositing"][kwin].
[kwin]: https://github.com/Genymobile/scrcpy/issues/114#issuecomment-378778613
### I get an error "Could not open video stream"
## Crashes
### Exception
There may be many reasons. One common cause is that the hardware encoder of your
device is not able to encode at the given definition:
```
ERROR: Exception on thread Thread[main,5,main]
android.media.MediaCodec$CodecException: Error 0xfffffc0e
...
Exit due to uncaughtException in main thread:
ERROR: Could not open video stream
INFO: Initial texture: 1080x2336
```
> ```
> ERROR: Exception on thread Thread[main,5,main]
> android.media.MediaCodec$CodecException: Error 0xfffffc0e
> ...
> Exit due to uncaughtException in main thread:
> ERROR: Could not open video stream
> INFO: Initial texture: 1080x2336
> ```
or
> ```
> ERROR: Exception on thread Thread[main,5,main]
> java.lang.IllegalStateException
> at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
> ```
Just try with a lower definition:

View File

@@ -188,7 +188,7 @@
identification within third-party archives.
Copyright (C) 2018 Genymobile
Copyright (C) 2018-2019 Romain Vimont
Copyright (C) 2018-2020 Romain Vimont
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -475,7 +475,7 @@ _²화면이 꺼진 상태에서 우클릭 시 다시 켜지며, 그 외의 상
## 라이선스
Copyright (C) 2018 Genymobile
Copyright (C) 2018-2019 Romain Vimont
Copyright (C) 2018-2020 Romain Vimont
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -37,8 +37,11 @@ control it using keyboard and mouse.
### Linux
On Linux, you typically need to [build the app manually][BUILD]. Don't worry,
it's not that hard.
In Debian (_testing_ and _sid_ for now):
```
apt install scrcpy
```
A [Snap] package is available: [`scrcpy`][snap-link].
@@ -56,20 +59,39 @@ For Gentoo, an [Ebuild] is available: [`scrcpy/`][ebuild-link].
[Ebuild]: https://wiki.gentoo.org/wiki/Ebuild
[ebuild-link]: https://github.com/maggu2810/maggu2810-overlay/tree/master/app-mobilephone/scrcpy
You could also [build the app manually][BUILD] (don't worry, it's not that
hard).
### Windows
For Windows, for simplicity, prebuilt archives with all the dependencies
(including `adb`) are available:
For Windows, for simplicity, a prebuilt archive with all the dependencies
(including `adb`) is available:
- [`scrcpy-win32-v1.12.1.zip`][direct-win32]
_(SHA-256: 0f4b3b063536b50a2df05dc42c760f9cc0093a9a26dbdf02d8232c74dab43480)_
- [`scrcpy-win64-v1.12.1.zip`][direct-win64]
_(SHA-256: 57d34b6d16cfd9fe169bc37c4df58ebd256d05c1ea3febc63d9cb0a027ab47c9)_
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v1.12.1/scrcpy-win32-v1.12.1.zip
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.12.1/scrcpy-win64-v1.12.1.zip
It is also available in [Chocolatey]:
[Chocolatey]: https://chocolatey.org/
```bash
choco install scrcpy
choco install adb # if you don't have it yet
```
And in [Scoop]:
```bash
scoop install scrcpy
scoop install adb # if you don't have it yet
```
[Scoop]: https://scoop.sh
You can also [build the app manually][BUILD].
@@ -137,14 +159,12 @@ scrcpy -b 2M # short version
#### Limit frame rate
The capture frame rate can be limited:
On devices with Android >= 10, the capture frame rate can be limited:
```bash
scrcpy --max-fps 15
```
This is officially supported since Android 10, but may work on earlier versions.
#### Crop
The device screen may be cropped to mirror only part of the screen.
@@ -216,6 +236,13 @@ scrcpy --serial 0123456789abcdef
scrcpy -s 0123456789abcdef # short version
```
If the device is connected over TCP/IP:
```bash
scrcpy --serial 192.168.0.1:5555
scrcpy -s 192.168.0.1:5555 # short version
```
You can start several instances of _scrcpy_ for several devices.
#### SSH tunnel
@@ -491,7 +518,7 @@ Read the [developers page].
## Licence
Copyright (C) 2018 Genymobile
Copyright (C) 2018-2019 Romain Vimont
Copyright (C) 2018-2020 Romain Vimont
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -76,9 +76,11 @@ cc = meson.get_compiler('c')
if host_machine.system() == 'windows'
src += [ 'src/sys/win/command.c' ]
src += [ 'src/sys/win/net.c' ]
dependencies += cc.find_library('ws2_32')
else
src += [ 'src/sys/unix/command.c' ]
src += [ 'src/sys/unix/net.c' ]
endif
conf = configuration_data()

View File

@@ -43,7 +43,7 @@ Print this help.
.TP
.BI "\-\-max\-fps " value
Limit the framerate of screen capture (officially supported since Android 10, but may work on earlier versions).
Limit the framerate of screen capture (only supported on devices with Android >= 10).
.TP
.BI "\-m, \-\-max\-size " value
@@ -261,7 +261,7 @@ Copyright \(co 2018 Genymobile
Genymobile
.UE
Copyright \(co 2018\-2019
Copyright \(co 2018\-2020
.MT rom@rom1v.com
Romain Vimont
.ME

View File

@@ -42,8 +42,8 @@ scrcpy_print_usage(const char *arg0) {
" Print this help.\n"
"\n"
" --max-fps value\n"
" Limit the frame rate of screen capture (officially supported\n"
" since Android 10, but may work on earlier versions).\n"
" Limit the frame rate of screen capture (only supported on\n"
" devices with Android >= 10).\n"
"\n"
" -m, --max-size value\n"
" Limit both the width and height of the video to value. The\n"

View File

@@ -4,6 +4,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "config.h"
#include "common.h"
@@ -202,3 +205,14 @@ process_check_success(process_t proc, const char *name) {
}
return true;
}
bool
is_regular_file(const char *path) {
struct stat path_stat;
int r = stat(path, &path_stat);
if (r) {
perror("stat");
return false;
}
return S_ISREG(path_stat.st_mode);
}

View File

@@ -75,8 +75,6 @@ control_msg_serialize(const struct control_msg *msg, unsigned char *buf) {
buf[1] = msg->set_screen_power_mode.mode;
return 2;
case CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON:
buf[1] = msg->back_or_screen_on.action;
return 2;
case CONTROL_MSG_TYPE_EXPAND_NOTIFICATION_PANEL:
case CONTROL_MSG_TYPE_COLLAPSE_NOTIFICATION_PANEL:
case CONTROL_MSG_TYPE_GET_CLIPBOARD:

View File

@@ -66,9 +66,6 @@ struct control_msg {
struct {
enum screen_power_mode mode;
} set_screen_power_mode;
struct {
enum android_keyevent_action action;
} back_or_screen_on;
};
};

View File

@@ -99,14 +99,9 @@ action_menu(struct controller *controller, int actions) {
// turn the screen on if it was off, press BACK otherwise
static void
press_back_or_turn_screen_on(struct controller *controller, int action) {
assert(action == ACTION_DOWN || action == ACTION_UP);
press_back_or_turn_screen_on(struct controller *controller) {
struct control_msg msg;
msg.type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON;
msg.back_or_screen_on.action = action == ACTION_DOWN
? AKEY_EVENT_ACTION_DOWN
: AKEY_EVENT_ACTION_UP;
if (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'press back or turn screen on'");
@@ -526,36 +521,31 @@ input_manager_process_mouse_button(struct input_manager *im,
// simulated from touch events, so it's a duplicate
return;
}
// double-click on black borders resize to fit the device screen
if (event->type == SDL_MOUSEBUTTONDOWN
&& event->button == SDL_BUTTON_LEFT
&& event->clicks == 2) {
bool outside = is_outside_device_screen(im, event->x, event->y);
if (outside) {
screen_resize_to_fit(im->screen);
if (event->type == SDL_MOUSEBUTTONDOWN) {
if (control && event->button == SDL_BUTTON_RIGHT) {
press_back_or_turn_screen_on(im->controller);
return;
}
if (control && event->button == SDL_BUTTON_MIDDLE) {
action_home(im->controller, ACTION_DOWN | ACTION_UP);
return;
}
// double-click on black borders resize to fit the device screen
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) {
bool outside =
is_outside_device_screen(im, event->x, event->y);
if (outside) {
screen_resize_to_fit(im->screen);
return;
}
}
// otherwise, send the click event to the device
}
if (!control) {
return;
}
if (event->button == SDL_BUTTON_MIDDLE) {
int action = event->type == SDL_MOUSEBUTTONDOWN ? ACTION_DOWN
: ACTION_UP;
action_home(im->controller, action);
return;
}
if (event->button == SDL_BUTTON_RIGHT) {
int action = event->type == SDL_MOUSEBUTTONDOWN ? ACTION_DOWN
: ACTION_UP;
press_back_or_turn_screen_on(im->controller, action);
return;
}
struct control_msg msg;
if (convert_mouse_button(event, im->screen, &msg)) {
if (!controller_push_msg(im->controller, &msg)) {

View File

@@ -6,13 +6,11 @@
#include <libgen.h>
#include <stdio.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_platform.h>
#include "config.h"
#include "command.h"
#include "util/log.h"
#include "util/net.h"
#include "util/str_util.h"
#define SOCKET_NAME "scrcpy"
#define SERVER_FILENAME "scrcpy-server"
@@ -20,39 +18,20 @@
#define DEFAULT_SERVER_PATH PREFIX "/share/scrcpy/" SERVER_FILENAME
#define DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar"
static char *
static const char *
get_server_path(void) {
#ifdef __WINDOWS__
const wchar_t *server_path_env = _wgetenv(L"SCRCPY_SERVER_PATH");
#else
const char *server_path_env = getenv("SCRCPY_SERVER_PATH");
#endif
if (server_path_env) {
LOGD("Using SCRCPY_SERVER_PATH: %s", server_path_env);
// if the envvar is set, use it
#ifdef __WINDOWS__
char *server_path = utf8_from_wide_char(server_path_env);
#else
char *server_path = SDL_strdup(server_path_env);
#endif
if (!server_path) {
LOGE("Could not allocate memory");
return NULL;
}
LOGD("Using SCRCPY_SERVER_PATH: %s", server_path);
return server_path;
return server_path_env;
}
#ifndef PORTABLE
LOGD("Using server: " DEFAULT_SERVER_PATH);
char *server_path = SDL_strdup(DEFAULT_SERVER_PATH);
if (!server_path) {
LOGE("Could not allocate memory");
return NULL;
}
// the absolute path is hardcoded
return server_path;
return DEFAULT_SERVER_PATH;
#else
// use scrcpy-server in the same directory as the executable
char *executable_path = get_executable_path();
if (!executable_path) {
@@ -88,17 +67,12 @@ get_server_path(void) {
static bool
push_server(const char *serial) {
char *server_path = get_server_path();
if (!server_path) {
return false;
}
const char *server_path = get_server_path();
if (!is_regular_file(server_path)) {
LOGE("'%s' does not exist or is not a regular file\n", server_path);
SDL_free(server_path);
return false;
}
process_t process = adb_push(serial, server_path, DEVICE_SERVER_PATH);
SDL_free(server_path);
return process_check_success(process, "adb push");
}

View File

@@ -15,7 +15,6 @@
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -128,14 +127,3 @@ get_executable_path(void) {
return NULL;
#endif
}
bool
is_regular_file(const char *path) {
struct stat path_stat;
if (stat(path, &path_stat)) {
perror("stat");
return false;
}
return S_ISREG(path_stat.st_mode);
}

21
app/src/sys/unix/net.c Normal file
View File

@@ -0,0 +1,21 @@
#include "util/net.h"
#include <unistd.h>
#include "config.h"
bool
net_init(void) {
// do nothing
return true;
}
void
net_cleanup(void) {
// do nothing
}
bool
net_close(socket_t socket) {
return !close(socket);
}

View File

@@ -4,8 +4,6 @@
#include "util/log.h"
#include "util/str_util.h"
#include <sys/stat.h>
static int
build_cmd(char *cmd, size_t len, const char *const argv[]) {
// Windows command-line parsing is WTF:
@@ -92,22 +90,3 @@ get_executable_path(void) {
buf[len] = '\0';
return utf8_from_wide_char(buf);
}
bool
is_regular_file(const char *path) {
wchar_t *wide_path = utf8_to_wide_char(path);
if (!wide_path) {
LOGC("Could not allocate wide char string");
return false;
}
struct _stat path_stat;
int r = _wstat(wide_path, &path_stat);
SDL_free(wide_path);
if (r) {
perror("stat");
return false;
}
return S_ISREG(path_stat.st_mode);
}

25
app/src/sys/win/net.c Normal file
View File

@@ -0,0 +1,25 @@
#include "util/net.h"
#include "config.h"
#include "util/log.h"
bool
net_init(void) {
WSADATA wsa;
int res = WSAStartup(MAKEWORD(2, 2), &wsa) < 0;
if (res < 0) {
LOGC("WSAStartup failed with error %d", res);
return false;
}
return true;
}
void
net_cleanup(void) {
WSACleanup();
}
bool
net_close(socket_t socket) {
return !closesocket(socket);
}

View File

@@ -1,7 +1,6 @@
#include "net.h"
#include <stdio.h>
#include <SDL2/SDL_platform.h>
#include "config.h"
#include "log.h"
@@ -116,32 +115,3 @@ bool
net_shutdown(socket_t socket, int how) {
return !shutdown(socket, how);
}
bool
net_init(void) {
#ifdef __WINDOWS__
WSADATA wsa;
int res = WSAStartup(MAKEWORD(2, 2), &wsa) < 0;
if (res < 0) {
LOGC("WSAStartup failed with error %d", res);
return false;
}
#endif
return true;
}
void
net_cleanup(void) {
#ifdef __WINDOWS__
WSACleanup();
#endif
}
bool
net_close(socket_t socket) {
#ifdef __WINDOWS__
return !closesocket(socket);
#else
return !close(socket);
#endif
}

View File

@@ -140,18 +140,14 @@ static void test_serialize_inject_scroll_event(void) {
static void test_serialize_back_or_screen_on(void) {
struct control_msg msg = {
.type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON,
.back_or_screen_on = {
.action = AKEY_EVENT_ACTION_UP,
},
};
unsigned char buf[CONTROL_MSG_SERIALIZED_MAX_SIZE];
int size = control_msg_serialize(&msg, buf);
assert(size == 2);
assert(size == 1);
const unsigned char expected[] = {
CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON,
AKEY_EVENT_ACTION_UP,
};
assert(!memcmp(buf, expected, sizeof(expected)));
}

View File

@@ -85,13 +85,6 @@ public final class ControlMessage {
return msg;
}
public static ControlMessage createBackOrScreenOn(int action) {
ControlMessage msg = new ControlMessage();
msg.type = TYPE_BACK_OR_SCREEN_ON;
msg.action = action;
return msg;
}
public static ControlMessage createEmpty(int type) {
ControlMessage msg = new ControlMessage();
msg.type = type;

View File

@@ -13,7 +13,6 @@ public class ControlMessageReader {
private static final int INJECT_TOUCH_EVENT_PAYLOAD_LENGTH = 21;
private static final int INJECT_SCROLL_EVENT_PAYLOAD_LENGTH = 20;
private static final int SET_SCREEN_POWER_MODE_PAYLOAD_LENGTH = 1;
private static final int BACK_OR_SCREEN_ON_PAYLOAD_LENGTH = 1;
public static final int TEXT_MAX_LENGTH = 300;
public static final int CLIPBOARD_TEXT_MAX_LENGTH = 4093;
@@ -74,8 +73,6 @@ public class ControlMessageReader {
msg = parseSetScreenPowerMode();
break;
case ControlMessage.TYPE_BACK_OR_SCREEN_ON:
msg = parseBackOrScreenOn();
break;
case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL:
case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL:
case ControlMessage.TYPE_GET_CLIPBOARD:
@@ -167,14 +164,6 @@ public class ControlMessageReader {
return ControlMessage.createSetScreenPowerMode(mode);
}
private ControlMessage parseBackOrScreenOn() {
if (buffer.remaining() < BACK_OR_SCREEN_ON_PAYLOAD_LENGTH) {
return null;
}
int action = toUnsigned(buffer.get());
return ControlMessage.createBackOrScreenOn(action);
}
private static Position readPosition(ByteBuffer buffer) {
int x = buffer.getInt();
int y = buffer.getInt();

View File

@@ -26,9 +26,6 @@ public class Controller {
private final MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[PointersState.MAX_POINTERS];
private final MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[PointersState.MAX_POINTERS];
private boolean backPressed;
private boolean powerPressed;
public Controller(Device device, DesktopConnection connection) {
this.device = device;
this.connection = connection;
@@ -91,7 +88,7 @@ public class Controller {
injectScroll(msg.getPosition(), msg.getHScroll(), msg.getVScroll());
break;
case ControlMessage.TYPE_BACK_OR_SCREEN_ON:
pressBackOrTurnScreenOn(msg.getAction());
pressBackOrTurnScreenOn();
break;
case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL:
device.expandNotificationPanel();
@@ -226,33 +223,8 @@ public class Controller {
return device.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
private boolean pressBackOrTurnScreenOn(int action) {
int keycode = -1;
if (action == KeyEvent.ACTION_UP) {
// if BACK or POWER were pressed, this action is the corresponding release event (regardless of the screen state)
if (backPressed) {
keycode = KeyEvent.KEYCODE_BACK;
backPressed = false;
} else if (powerPressed) {
keycode = KeyEvent.KEYCODE_POWER;
powerPressed = false;
}
}
if (keycode == -1) {
keycode = device.isScreenOn() ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_POWER;
}
if (action == KeyEvent.ACTION_DOWN) {
if (keycode == KeyEvent.KEYCODE_BACK) {
backPressed = true;
powerPressed = false;
} else {
backPressed = false;
powerPressed = true;
}
}
return injectKeyEvent(action, keycode, 0, 0);
private boolean pressBackOrTurnScreenOn() {
int keycode = device.isScreenOn() ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_POWER;
return injectKeycode(keycode);
}
}

View File

@@ -19,7 +19,6 @@ public class ScreenEncoder implements Device.RotationListener {
private static final int DEFAULT_I_FRAME_INTERVAL = 10; // seconds
private static final int REPEAT_FRAME_DELAY_US = 100_000; // repeat after 100ms
private static final String KEY_MAX_FPS_TO_ENCODER = "max-fps-to-encoder";
private static final int NO_PTS = -1;
@@ -151,10 +150,11 @@ public class ScreenEncoder implements Device.RotationListener {
// display the very first frame, and recover from bad quality when no new frames
format.setLong(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, REPEAT_FRAME_DELAY_US); // µs
if (maxFps > 0) {
// The key existed privately before Android 10:
// <https://android.googlesource.com/platform/frameworks/base/+/625f0aad9f7a259b6881006ad8710adce57d1384%5E%21/>
// <https://github.com/Genymobile/scrcpy/issues/488#issuecomment-567321437>
format.setFloat(KEY_MAX_FPS_TO_ENCODER, maxFps);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
format.setFloat(MediaFormat.KEY_MAX_FPS_TO_ENCODER, maxFps);
} else {
Ln.w("Max FPS is only supported since Android 10, the option has been ignored");
}
}
return format;
}

View File

@@ -145,7 +145,6 @@ public class ControlMessageReaderTest {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeByte(ControlMessage.TYPE_BACK_OR_SCREEN_ON);
dos.writeByte(KeyEvent.ACTION_UP);
byte[] packet = bos.toByteArray();
@@ -153,7 +152,6 @@ public class ControlMessageReaderTest {
ControlMessage event = reader.next();
Assert.assertEquals(ControlMessage.TYPE_BACK_OR_SCREEN_ON, event.getType());
Assert.assertEquals(KeyEvent.ACTION_UP, event.getAction());
}
@Test