Add rotation support for non-default display

Use new methods introduced by this commit:
<90c9005e68%5E%21/>

PR #4698 <https://github.com/Genymobile/scrcpy/pull/4698>

Signed-off-by: Romain Vimont <rom@rom1v.com>
pull/4658/merge
eiyooooo 3 months ago committed by Romain Vimont
parent 746eaea556
commit d894e270a7

@ -180,7 +180,7 @@ public class Controller implements AsyncProcessor {
} }
break; break;
case ControlMessage.TYPE_ROTATE_DEVICE: case ControlMessage.TYPE_ROTATE_DEVICE:
Device.rotateDevice(); device.rotateDevice();
break; break;
default: default:
// do nothing // do nothing

@ -359,21 +359,30 @@ public final class Device {
/** /**
* Disable auto-rotation (if enabled), set the screen rotation and re-enable auto-rotation (if it was enabled). * 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(); WindowManager wm = ServiceManager.getWindowManager();
boolean accelerometerRotation = !wm.isRotationFrozen(); boolean accelerometerRotation = !wm.isRotationFrozen(displayId);
int currentRotation = wm.getRotation(); int currentRotation = getCurrentRotation(displayId);
int newRotation = (currentRotation & 1) ^ 1; // 0->1, 1->0, 2->1, 3->0 int newRotation = (currentRotation & 1) ^ 1; // 0->1, 1->0, 2->1, 3->0
String newRotationString = newRotation == 0 ? "portrait" : "landscape"; String newRotationString = newRotation == 0 ? "portrait" : "landscape";
Ln.i("Device rotation requested: " + newRotationString); Ln.i("Device rotation requested: " + newRotationString);
wm.freezeRotation(newRotation); wm.freezeRotation(displayId, newRotation);
// restore auto-rotate if necessary // restore auto-rotate if necessary
if (accelerometerRotation) { if (accelerometerRotation) {
wm.thawRotation(); wm.thawRotation(displayId);
} }
} }
private static int getCurrentRotation(int displayId) {
if (displayId == 0) {
return ServiceManager.getWindowManager().getRotation();
}
DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId);
return displayInfo.getRotation();
}
} }

@ -13,8 +13,11 @@ public final class WindowManager {
private final IInterface manager; private final IInterface manager;
private Method getRotationMethod; private Method getRotationMethod;
private Method freezeRotationMethod; private Method freezeRotationMethod;
private Method freezeDisplayRotationMethod;
private Method isRotationFrozenMethod; private Method isRotationFrozenMethod;
private Method isDisplayRotationFrozenMethod;
private Method thawRotationMethod; private Method thawRotationMethod;
private Method thawDisplayRotationMethod;
static WindowManager create() { static WindowManager create() {
IInterface manager = ServiceManager.getService("window", "android.view.IWindowManager"); IInterface manager = ServiceManager.getService("window", "android.view.IWindowManager");
@ -47,6 +50,15 @@ public final class WindowManager {
return freezeRotationMethod; return freezeRotationMethod;
} }
// New method added by this commit:
// <https://android.googlesource.com/platform/frameworks/base/+/90c9005e687aa0f63f1ac391adc1e8878ab31759%5E%21/>
private Method getFreezeDisplayRotationMethod() throws NoSuchMethodException {
if (freezeDisplayRotationMethod == null) {
freezeDisplayRotationMethod = manager.getClass().getMethod("freezeDisplayRotation", int.class, int.class);
}
return freezeDisplayRotationMethod;
}
private Method getIsRotationFrozenMethod() throws NoSuchMethodException { private Method getIsRotationFrozenMethod() throws NoSuchMethodException {
if (isRotationFrozenMethod == null) { if (isRotationFrozenMethod == null) {
isRotationFrozenMethod = manager.getClass().getMethod("isRotationFrozen"); isRotationFrozenMethod = manager.getClass().getMethod("isRotationFrozen");
@ -54,6 +66,15 @@ public final class WindowManager {
return isRotationFrozenMethod; return isRotationFrozenMethod;
} }
// New method added by this commit:
// <https://android.googlesource.com/platform/frameworks/base/+/90c9005e687aa0f63f1ac391adc1e8878ab31759%5E%21/>
private Method getIsDisplayRotationFrozenMethod() throws NoSuchMethodException {
if (isDisplayRotationFrozenMethod == null) {
isDisplayRotationFrozenMethod = manager.getClass().getMethod("isDisplayRotationFrozen", int.class);
}
return isDisplayRotationFrozenMethod;
}
private Method getThawRotationMethod() throws NoSuchMethodException { private Method getThawRotationMethod() throws NoSuchMethodException {
if (thawRotationMethod == null) { if (thawRotationMethod == null) {
thawRotationMethod = manager.getClass().getMethod("thawRotation"); thawRotationMethod = manager.getClass().getMethod("thawRotation");
@ -61,6 +82,15 @@ public final class WindowManager {
return thawRotationMethod; return thawRotationMethod;
} }
// New method added by this commit:
// <https://android.googlesource.com/platform/frameworks/base/+/90c9005e687aa0f63f1ac391adc1e8878ab31759%5E%21/>
private Method getThawDisplayRotationMethod() throws NoSuchMethodException {
if (thawDisplayRotationMethod == null) {
thawDisplayRotationMethod = manager.getClass().getMethod("thawDisplayRotation", int.class);
}
return thawDisplayRotationMethod;
}
public int getRotation() { public int getRotation() {
try { try {
Method method = getGetRotationMethod(); Method method = getGetRotationMethod();
@ -71,29 +101,57 @@ public final class WindowManager {
} }
} }
public void freezeRotation(int rotation) { public void freezeRotation(int displayId, int rotation) {
try { try {
Method method = getFreezeRotationMethod(); try {
method.invoke(manager, rotation); 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) { } catch (ReflectiveOperationException e) {
Ln.e("Could not invoke method", e); Ln.e("Could not invoke method", e);
} }
} }
public boolean isRotationFrozen() { public boolean isRotationFrozen(int displayId) {
try { try {
Method method = getIsRotationFrozenMethod(); try {
return (boolean) method.invoke(manager); 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) { } catch (ReflectiveOperationException e) {
Ln.e("Could not invoke method", e); Ln.e("Could not invoke method", e);
return false; return false;
} }
} }
public void thawRotation() { public void thawRotation(int displayId) {
try { try {
Method method = getThawRotationMethod(); try {
method.invoke(manager); 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) { } catch (ReflectiveOperationException e) {
Ln.e("Could not invoke method", e); Ln.e("Could not invoke method", e);
} }

Loading…
Cancel
Save