Skip to content
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

Add rotation support for non default display #4698

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion server/src/main/java/com/genymobile/scrcpy/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ private void handleEvent() throws IOException {
}
break;
case ControlMessage.TYPE_ROTATE_DEVICE:
Device.rotateDevice();
device.rotateDevice();
break;
default:
// do nothing
Expand Down
16 changes: 10 additions & 6 deletions server/src/main/java/com/genymobile/scrcpy/Device.java
Original file line number Diff line number Diff line change
Expand Up @@ -359,21 +359,25 @@ public static boolean powerOffScreen(int displayId) {
/**
* Disable auto-rotation (if enabled), set the screen rotation and re-enable auto-rotation (if it was enabled).
*/
public static void rotateDevice() {
public void rotateDevice() {
WindowManager wm = ServiceManager.getWindowManager();

boolean accelerometerRotation = !wm.isRotationFrozen();
boolean accelerometerRotation = !wm.isRotationFrozen(displayId);

int currentRotation = wm.getRotation();
int currentRotation;
if (displayId != 0) {
DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId);
currentRotation = displayInfo.getRotation();
} else currentRotation = wm.getRotation();
int newRotation = (currentRotation & 1) ^ 1; // 0->1, 1->0, 2->1, 3->0
String newRotationString = newRotation == 0 ? "portrait" : "landscape";

Ln.i("Device rotation requested: " + newRotationString);
wm.freezeRotation(newRotation);
wm.freezeRotation(displayId, newRotation);

// restore auto-rotate if necessary
if (accelerometerRotation) {
wm.thawRotation();
wm.thawRotation(displayId);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ public final class WindowManager {
private final IInterface manager;
private Method getRotationMethod;
private Method freezeRotationMethod;
private Method freezeDisplayRotationMethod;
private Method isRotationFrozenMethod;
private Method isDisplayRotationFrozenMethod;
private Method thawRotationMethod;
private Method thawDisplayRotationMethod;

static WindowManager create() {
IInterface manager = ServiceManager.getService("window", "android.view.IWindowManager");
Expand Down Expand Up @@ -47,20 +50,47 @@ private Method getFreezeRotationMethod() throws NoSuchMethodException {
return freezeRotationMethod;
}

// new method added since this commit:
// https://android.googlesource.com/platform/frameworks/base/+/90c9005e687aa0f63f1ac391adc1e8878ab31759%5E%21/#F0
private Method getFreezeDisplayRotationMethod() throws NoSuchMethodException {
if (freezeDisplayRotationMethod == null) {
freezeDisplayRotationMethod = manager.getClass().getMethod("freezeDisplayRotation", int.class, int.class);
}
return freezeDisplayRotationMethod;
}

private Method getIsRotationFrozenMethod() throws NoSuchMethodException {
if (isRotationFrozenMethod == null) {
isRotationFrozenMethod = manager.getClass().getMethod("isRotationFrozen");
}
return isRotationFrozenMethod;
}

// new method added since this commit:
// https://android.googlesource.com/platform/frameworks/base/+/90c9005e687aa0f63f1ac391adc1e8878ab31759%5E%21/#F0
private Method getIsDisplayRotationFrozenMethod() throws NoSuchMethodException {
if (isDisplayRotationFrozenMethod == null) {
isDisplayRotationFrozenMethod = manager.getClass().getMethod("isDisplayRotationFrozen", int.class);
}
return isDisplayRotationFrozenMethod;
}

private Method getThawRotationMethod() throws NoSuchMethodException {
if (thawRotationMethod == null) {
thawRotationMethod = manager.getClass().getMethod("thawRotation");
}
return thawRotationMethod;
}

// new method added since this commit:
// https://android.googlesource.com/platform/frameworks/base/+/90c9005e687aa0f63f1ac391adc1e8878ab31759%5E%21/#F0
private Method getThawDisplayRotationMethod() throws NoSuchMethodException {
if (thawDisplayRotationMethod == null) {
thawDisplayRotationMethod = manager.getClass().getMethod("thawDisplayRotation", int.class);
}
return thawDisplayRotationMethod;
}

public int getRotation() {
try {
Method method = getGetRotationMethod();
Expand All @@ -71,29 +101,53 @@ public int getRotation() {
}
}

public void freezeRotation(int rotation) {
public void freezeRotation(int displayId, int rotation) {
try {
Method method = getFreezeRotationMethod();
method.invoke(manager, rotation);
try {
Method method = getFreezeDisplayRotationMethod();
method.invoke(manager, displayId, rotation);
} catch (ReflectiveOperationException e) {
if (displayId == 0) {
Method method = getFreezeRotationMethod();
method.invoke(manager, rotation);
} else Ln.e("Could not invoke method", e);
}
} catch (ReflectiveOperationException e) {
Ln.e("Could not invoke method", e);
}
}

public boolean isRotationFrozen() {
public boolean isRotationFrozen(int displayId) {
try {
Method method = getIsRotationFrozenMethod();
return (boolean) method.invoke(manager);
try {
Method method = getIsDisplayRotationFrozenMethod();
return (boolean) method.invoke(manager, displayId);
} catch (ReflectiveOperationException e) {
if (displayId == 0) {
Method method = getIsRotationFrozenMethod();
return (boolean) method.invoke(manager);
} else {
Ln.e("Could not invoke method", e);
return false;
}
}
} catch (ReflectiveOperationException e) {
Ln.e("Could not invoke method", e);
return false;
}
}

public void thawRotation() {
public void thawRotation(int displayId) {
try {
Method method = getThawRotationMethod();
method.invoke(manager);
try {
Method method = getThawDisplayRotationMethod();
method.invoke(manager, displayId);
} catch (ReflectiveOperationException e) {
if (displayId == 0) {
Method method = getThawRotationMethod();
method.invoke(manager);
} else Ln.e("Could not invoke method", e);
}
} catch (ReflectiveOperationException e) {
Ln.e("Could not invoke method", e);
}
Expand Down