-
-
Notifications
You must be signed in to change notification settings - Fork 10.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix turn screen off on Android 14 #4456
Conversation
On Android 14, the methods to access the display have been moved to DisplayControl, which is not in the core framework. Use a specific ClassLoader to access this class and its native dependencies. Fixes #3927 <#3927> Refs #3927 comment <#3927 (comment)> Refs #4446 comment <#4446 (comment)> PR #4456 <#4456> Co-authored-by: Simon Chan <[email protected]> Signed-off-by: Romain Vimont <[email protected]>
55c5945
to
5d4b8a7
Compare
@yume-chan I noticed by accident that, on Android 14 (Pixel 8), turning the screen on in the cleanup process makes app_process crash:
Despite this crash, the screen is turned on correctly. In fact, it crashes when the process terminates, for example, in this case, it crashes 5 seconds later: diff --git a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
index b3a1aac13..006736c1a 100644
--- a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
+++ b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
@@ -2,6 +2,7 @@ package com.genymobile.scrcpy;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.util.Base64;
import java.io.File;
@@ -187,5 +188,7 @@ public final class CleanUp {
Device.setScreenPowerMode(Device.POWER_MODE_NORMAL);
}
}
+
+ SystemClock.sleep(5000);
}
} However, if I don't restore the power mode, then it does not crash: diff --git a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
index b3a1aac13..eaf16a3b8 100644
--- a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
+++ b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
@@ -184,7 +184,6 @@ public final class CleanUp {
Device.powerOffScreen(config.displayId);
} else if (config.restoreNormalPowerMode) {
Ln.i("Restoring normal power mode");
- Device.setScreenPowerMode(Device.POWER_MODE_NORMAL);
}
}
} Turning the screen off or on in the main scrcpy process works without crashing. Any idea why? |
I have no idea. I tried my POC and it also crashes on exit. Why Scrcpy main process doesn't crash sounds like a bigger question. I tried to debug the process. By adding Searching "SIGSEGV cxa_finalize" shows that if a module has destructors registered using Anyway, if this crash causes system instability, we can try to switch to #4446 (comment). The transaction ID might change between versions, but overall I believe this is the best. We can also call public void setPowerMode(IBinder display, int mode) {
var data = Parcel.obtain();
var reply = Parcel.obtain();
try {
data.writeInterfaceToken("android.gui.ISurfaceComposer");
data.writeStrongBinder(display);
data.writeInt(mode);
surfaceComposer.transact(IBinder.FIRST_CALL_TRANSACTION + 8, data, reply, 0);
reply.readException();
} catch (RemoteException e) {
throw new RuntimeException(e);
} finally {
data.recycle();
reply.recycle();
}
} |
The reason is that the main process calls If I do the same for cleanup, it "solves" the problem too: diff --git a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
index b3a1aac13..c84e25bb8 100644
--- a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
+++ b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java
@@ -187,5 +187,7 @@ public final class CleanUp {
Device.setScreenPowerMode(Device.POWER_MODE_NORMAL);
}
}
+
+ System.exit(0);
}
} In any case, I think restoring the display power mode to normal on exit should only be called when it is not already in that state. But for that, the main process must notify the cleanup process every time MOD+o or MOD+Shift+o is pressed. So CleanUp should not get its parameters from the command line, but receive changes from the main process via stdin/stdout… I'll probably do that in the future. |
This avoids an internal crash reported in `adb logcat`. Refs #4456 <#4456 (comment)>
Setting the power mode with this mechanism on Android 14 causes issues on some devices (the device reboots after a few minutes): #4624 |
Some actions may be performed when scrcpy exits, currently: - disable "show touches" - restore "stay on while plugged in" - power off screen - restore "power mode" (to disable "turn screen off") They are performed from a separate process so that they can be executed even when scrcpy-server is killed (e.g. if the device is unplugged). The clean up actions to perform were configured when scrcpy started. Given that there is no method to read the current "power mode" in Android, and that "turn screen off" can be applied at any time using an scrcpy shortcut, there was no way to determine if "power mode" had to be restored on exit. Therefore, it was always restored to "normal", even when not necessary. However, setting the "power mode" is quite fragile on some devices, and may cause some issues, so it is preferable to call it only when necessary (when "turn screen off" has actually been called). For that purpose, make the scrcpy-server main process and the clean up process communicate the actions to perform over the stdout/stdin, so that they can be changed dynamically. In particular, when the power mode is changed at runtime, notify the clean up process. Refs 1beec99 Refs #4456 <#4456> Refs #4624 <#4624>
I just implemented that this week-end: #4649 |
Some actions may be performed when scrcpy exits, currently: - disable "show touches" - restore "stay on while plugged in" - power off screen - restore "power mode" (to disable "turn screen off") They are performed from a separate process so that they can be executed even when scrcpy-server is killed (e.g. if the device is unplugged). The clean up actions to perform were configured when scrcpy started. Given that there is no method to read the current "power mode" in Android, and that "turn screen off" can be applied at any time using an scrcpy shortcut, there was no way to determine if "power mode" had to be restored on exit. Therefore, it was always restored to "normal", even when not necessary. However, setting the "power mode" is quite fragile on some devices, and may cause some issues, so it is preferable to call it only when necessary (when "turn screen off" has actually been called). For that purpose, make the scrcpy-server main process and the clean up process communicate the actions to perform over the stdout/stdin, so that they can be changed dynamically. In particular, when the power mode is changed at runtime, notify the clean up process. Refs 1beec99 Refs #4456 <#4456> Refs #4624 <#4624> PR #4649 <#4649>
Some actions may be performed when scrcpy exits, currently: - disable "show touches" - restore "stay on while plugged in" - power off screen - restore "power mode" (to disable "turn screen off") They are performed from a separate process so that they can be executed even when scrcpy-server is killed (e.g. if the device is unplugged). The clean up actions to perform were configured when scrcpy started. Given that there is no method to read the current "power mode" in Android, and that "turn screen off" can be applied at any time using an scrcpy shortcut, there was no way to determine if "power mode" had to be restored on exit. Therefore, it was always restored to "normal", even when not necessary. However, setting the "power mode" is quite fragile on some devices, and may cause some issues, so it is preferable to call it only when necessary (when "turn screen off" has actually been called). For that purpose, make the scrcpy-server main process and the clean up process communicate the actions to perform over a pipe (stdin/stdout), so that they can be changed dynamically. In particular, when the power mode is changed at runtime, notify the clean up process. Refs 1beec99 Refs #4456 <#4456> Refs #4624 <#4624> PR #4649 <#4649>
A new PR to replace #4446.
On Android 14, the methods to access the display have been moved to DisplayControl, which is not in the core framework. Use a specific ClassLoader to access this class and its native dependencies.
Fixes #3927
Refs #3927 (comment)
Refs #4446 (comment)
cc @yume-chan
Here is a binary for Windows:
scrcpy-turnscreenoff-android14-pr4456.zip
SHA-256: 08bee09002ec8869c39b884d02f59a272301b75c01c15eb8beab255ef1ddd871