Skip to content

Commit

Permalink
Add workaround for Samsung devices issues
Browse files Browse the repository at this point in the history
On some Samsung devices, DisplayManagerGlobal.getDisplayInfoLocked()
calls ActivityThread.currentActivityThread().getConfiguration(), which
requires a non-null ConfigurationController.

Fixes <#4467>
  • Loading branch information
rom1v committed Nov 27, 2023
1 parent 4135c41 commit 140a49b
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions server/src/main/java/com/genymobile/scrcpy/Workarounds.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ private Workarounds() {
}

public static void apply(boolean audio, boolean camera) {
boolean mustFillConfigurationController = false;
boolean mustFillAppInfo = false;
boolean mustFillAppContext = false;

Expand Down Expand Up @@ -85,11 +86,23 @@ public static void apply(boolean audio, boolean camera) {
mustFillAppContext = true;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// On some Samsung devices, DisplayManagerGlobal.getDisplayInfoLocked() calls ActivityThread.currentActivityThread().getConfiguration(),
// which requires a non-null ConfigurationController.
// ConfigurationController was introduced in Android 12, so do not attempt to set it on lower versions.
// <https://github.com/Genymobile/scrcpy/issues/4467>
mustFillConfigurationController = true;
}

if (mustFillConfigurationController) {
// Must be call before fillAppContext() because it is necessary to get a valid system context
fillConfigurationController();
}
if (mustFillAppInfo) {
Workarounds.fillAppInfo();
fillAppInfo();
}
if (mustFillAppContext) {
Workarounds.fillAppContext();
fillAppContext();
}
}

Expand Down Expand Up @@ -149,6 +162,22 @@ private static void fillAppContext() {
}
}

private static void fillConfigurationController() {
try {
Class<?> configurationControllerClass = Class.forName("android.app.ConfigurationController");
Class<?> activityThreadInternalClass = Class.forName("android.app.ActivityThreadInternal");
Constructor<?> configurationControllerConstructor = configurationControllerClass.getDeclaredConstructor(activityThreadInternalClass);
configurationControllerConstructor.setAccessible(true);
Object configurationController = configurationControllerConstructor.newInstance(ACTIVITY_THREAD);

Field configurationControllerField = ACTIVITY_THREAD_CLASS.getDeclaredField("mConfigurationController");
configurationControllerField.setAccessible(true);
configurationControllerField.set(ACTIVITY_THREAD, configurationController);
} catch (Throwable throwable) {
Ln.d("Could not fill configuration: " + throwable.getMessage());
}
}

static Context getSystemContext() {
try {
Method getSystemContextMethod = ACTIVITY_THREAD_CLASS.getDeclaredMethod("getSystemContext");
Expand Down

1 comment on commit 140a49b

@sameastham
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this! This fixed the issue I was having when using scrcpy with my S23 Ultra.

Please sign in to comment.