mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-02-26 16:24:30 +01:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c21e8886b4 | ||
|
|
0034082d47 | ||
|
|
8cd63cb63e | ||
|
|
cc309a2b34 | ||
|
|
91a4a74641 | ||
|
|
48f38c4bb6 | ||
|
|
6875e9aa88 | ||
|
|
1a0d300786 | ||
|
|
d2447b5c19 | ||
|
|
882003f314 |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -84,7 +84,7 @@ jobs:
|
||||
run: release/test_client.sh
|
||||
|
||||
build-linux-x86_64:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Check architecture
|
||||
run: |
|
||||
|
||||
@@ -58,7 +58,7 @@ Make sure you [enabled USB debugging][enable-adb] on your device(s).
|
||||
On some devices (especially Xiaomi), you might get the following error:
|
||||
|
||||
```
|
||||
java.lang.SecurityException: Injecting input events requires the caller (or the source of the instrumentation, if any) to have the INJECT_EVENTS permission.
|
||||
Injecting input events requires the caller (or the source of the instrumentation, if any) to have the INJECT_EVENTS permission.
|
||||
```
|
||||
|
||||
In that case, you need to enable [an additional option][control] `USB debugging
|
||||
|
||||
@@ -205,6 +205,7 @@ _scrcpy() {
|
||||
|-p|--port \
|
||||
|--push-target \
|
||||
|--rotation \
|
||||
|--screen-off-timeout \
|
||||
|--tunnel-host \
|
||||
|--tunnel-port \
|
||||
|--v4l2-buffer \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#compdef -N scrcpy -N scrcpy.exe
|
||||
#compdef scrcpy scrcpy.exe
|
||||
#
|
||||
# name: scrcpy
|
||||
# auth: hltdev [hltdev8642@gmail.com]
|
||||
@@ -11,7 +11,7 @@ arguments=(
|
||||
'--always-on-top[Make scrcpy window always on top \(above other windows\)]'
|
||||
'--angle=[Rotate the video content by a custom angle, in degrees]'
|
||||
'--audio-bit-rate=[Encode the audio at the given bit-rate]'
|
||||
'--audio-buffer=[Configure the audio buffering delay (in milliseconds)]'
|
||||
'--audio-buffer=[Configure the audio buffering delay \(in milliseconds\)]'
|
||||
'--audio-codec=[Select the audio codec]:codec:(opus aac flac raw)'
|
||||
'--audio-codec-options=[Set a list of comma-separated key\:type=value options for the device audio encoder]'
|
||||
'--audio-dup=[Duplicate audio]'
|
||||
@@ -35,10 +35,10 @@ arguments=(
|
||||
{-e,--select-tcpip}'[Use TCP/IP device]'
|
||||
{-f,--fullscreen}'[Start in fullscreen]'
|
||||
'--force-adb-forward[Do not attempt to use \"adb reverse\" to connect to the device]'
|
||||
'-G[Use UHID/AOA gamepad (same as --gamepad=uhid or --gamepad=aoa, depending on OTG mode)]'
|
||||
'-G[Use UHID/AOA gamepad \(same as --gamepad=uhid or --gamepad=aoa, depending on OTG mode\)]'
|
||||
'--gamepad=[Set the gamepad input mode]:mode:(disabled uhid aoa)'
|
||||
{-h,--help}'[Print the help]'
|
||||
'-K[Use UHID/AOA keyboard (same as --keyboard=uhid or --keyboard=aoa, depending on OTG mode)]'
|
||||
'-K[Use UHID/AOA keyboard \(same as --keyboard=uhid or --keyboard=aoa, depending on OTG mode\)]'
|
||||
'--keyboard=[Set the keyboard input mode]:mode:(disabled sdk uhid aoa)'
|
||||
'--kill-adb-on-close[Kill adb when scrcpy terminates]'
|
||||
'--legacy-paste[Inject computer clipboard text as a sequence of key events on Ctrl+v]'
|
||||
@@ -48,7 +48,7 @@ arguments=(
|
||||
'--list-displays[List displays available on the device]'
|
||||
'--list-encoders[List video and audio encoders available on the device]'
|
||||
{-m,--max-size=}'[Limit both the width and height of the video to value]'
|
||||
'-M[Use UHID/AOA mouse (same as --mouse=uhid or --mouse=aoa, depending on OTG mode)]'
|
||||
'-M[Use UHID/AOA mouse \(same as --mouse=uhid or --mouse=aoa, depending on OTG mode\)]'
|
||||
'--max-fps=[Limit the frame rate of screen capture]'
|
||||
'--mouse=[Set the mouse input mode]:mode:(disabled sdk uhid aoa)'
|
||||
'--mouse-bind=[Configure bindings of secondary clicks]'
|
||||
|
||||
@@ -510,6 +510,10 @@ The device serial number. Mandatory only if several devices are connected to adb
|
||||
.B \-S, \-\-turn\-screen\-off
|
||||
Turn the device screen off immediately.
|
||||
|
||||
.TP
|
||||
.B "\-\-screen\-off\-timeout " seconds
|
||||
Set the screen off timeout while scrcpy is running (restore the initial value on exit).
|
||||
|
||||
.TP
|
||||
.BI "\-\-shortcut\-mod " key\fR[+...]][,...]
|
||||
Specify the modifiers to use for scrcpy shortcuts. Possible keys are "lctrl", "rctrl", "lalt", "ralt", "lsuper" and "rsuper".
|
||||
|
||||
@@ -165,7 +165,7 @@ sdl_configure(bool video_playback, bool disable_screensaver) {
|
||||
}
|
||||
|
||||
static enum scrcpy_exit_code
|
||||
event_loop(struct scrcpy *s) {
|
||||
event_loop(struct scrcpy *s, bool has_screen) {
|
||||
SDL_Event event;
|
||||
while (SDL_WaitEvent(&event)) {
|
||||
switch (event.type) {
|
||||
@@ -197,7 +197,7 @@ event_loop(struct scrcpy *s) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (!sc_screen_handle_event(&s->screen, &event)) {
|
||||
if (has_screen && !sc_screen_handle_event(&s->screen, &event)) {
|
||||
return SCRCPY_EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
@@ -933,7 +933,7 @@ aoa_complete:
|
||||
}
|
||||
}
|
||||
|
||||
ret = event_loop(s);
|
||||
ret = event_loop(s, options->window);
|
||||
terminate_event_loop();
|
||||
LOGD("quit...");
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,11 @@ public enum Orientation {
|
||||
throw new IllegalArgumentException("Unknown orientation: " + name);
|
||||
}
|
||||
|
||||
public static Orientation fromRotation(int rotation) {
|
||||
assert rotation >= 0 && rotation < 4;
|
||||
return values()[rotation];
|
||||
public static Orientation fromRotation(int ccwRotation) {
|
||||
assert ccwRotation >= 0 && ccwRotation < 4;
|
||||
// Display rotation is expressed counter-clockwise, orientation is expressed clockwise
|
||||
int cwRotation = (4 - ccwRotation) % 4;
|
||||
return values()[cwRotation];
|
||||
}
|
||||
|
||||
public boolean isFlipped() {
|
||||
|
||||
@@ -95,12 +95,12 @@ public final class DisplayManager {
|
||||
}
|
||||
|
||||
private static int parseDisplayFlags(String text) {
|
||||
Pattern regex = Pattern.compile("FLAG_[A-Z_]+");
|
||||
if (text == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
Pattern regex = Pattern.compile("FLAG_[A-Z_]+");
|
||||
Matcher m = regex.matcher(text);
|
||||
while (m.find()) {
|
||||
String flagString = m.group();
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.annotation.SuppressLint;
|
||||
import android.view.InputEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@SuppressLint("PrivateApi,DiscouragedPrivateApi")
|
||||
@@ -17,6 +18,7 @@ public final class InputManager {
|
||||
|
||||
private final Object manager;
|
||||
private Method injectInputEventMethod;
|
||||
private long lastPermissionLogDate;
|
||||
|
||||
private static Method setDisplayIdMethod;
|
||||
private static Method setActionButtonMethod;
|
||||
@@ -57,6 +59,23 @@ public final class InputManager {
|
||||
Method method = getInjectInputEventMethod();
|
||||
return (boolean) method.invoke(manager, inputEvent, mode);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
if (e instanceof InvocationTargetException) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof SecurityException) {
|
||||
String message = e.getCause().getMessage();
|
||||
if (message != null && message.contains("INJECT_EVENTS permission")) {
|
||||
// Do not flood the console, limit to one permission error log every 3 seconds
|
||||
long now = System.currentTimeMillis();
|
||||
if (lastPermissionLogDate <= now - 3000) {
|
||||
Ln.e(message);
|
||||
Ln.e("Make sure you have enabled \"USB debugging (Security Settings)\" and then rebooted your device.");
|
||||
lastPermissionLogDate = now;
|
||||
}
|
||||
// Do not print the stack trace
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ln.e("Could not invoke method", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user