diff --git a/server/src/main/java/com/genymobile/scrcpy/display/DisplaySizeMonitor.java b/server/src/main/java/com/genymobile/scrcpy/display/DisplayMonitor.java similarity index 70% rename from server/src/main/java/com/genymobile/scrcpy/display/DisplaySizeMonitor.java rename to server/src/main/java/com/genymobile/scrcpy/display/DisplayMonitor.java index b8e4e6f2..5a31fff5 100644 --- a/server/src/main/java/com/genymobile/scrcpy/display/DisplaySizeMonitor.java +++ b/server/src/main/java/com/genymobile/scrcpy/display/DisplayMonitor.java @@ -2,7 +2,6 @@ package com.genymobile.scrcpy.display; import com.genymobile.scrcpy.AndroidVersions; import com.genymobile.scrcpy.device.Device; -import com.genymobile.scrcpy.model.Size; import com.genymobile.scrcpy.util.Ln; import com.genymobile.scrcpy.wrappers.DisplayManager; import com.genymobile.scrcpy.wrappers.DisplayWindowListener; @@ -14,10 +13,10 @@ import android.os.Handler; import android.os.HandlerThread; import android.view.IDisplayWindowListener; -public class DisplaySizeMonitor { +public class DisplayMonitor { public interface Listener { - void onDisplaySizeChanged(); + void onDisplayPropertiesChanged(); } // On Android 14, DisplayListener may be broken (it never sends events). This is fixed in recent Android 14 upgrades, but we can't really @@ -33,7 +32,7 @@ public class DisplaySizeMonitor { private int displayId = Device.DISPLAY_ID_NONE; - private Size sessionDisplaySize; + private DisplayProperties props; private Listener listener; @@ -51,11 +50,11 @@ public class DisplaySizeMonitor { Handler handler = new Handler(handlerThread.getLooper()); displayListenerHandle = ServiceManager.getDisplayManager().registerDisplayListener(eventDisplayId -> { if (Ln.isEnabled(Ln.Level.VERBOSE)) { - Ln.v("DisplaySizeMonitor: onDisplayChanged(" + eventDisplayId + ")"); + Ln.v("DisplayMonitor: onDisplayChanged(" + eventDisplayId + ")"); } if (eventDisplayId == displayId) { - checkDisplaySizeChanged(); + checkDisplayPropertiesChanged(); } }, handler); } else { @@ -63,11 +62,11 @@ public class DisplaySizeMonitor { @Override public void onDisplayConfigurationChanged(int eventDisplayId, Configuration newConfig) { if (Ln.isEnabled(Ln.Level.VERBOSE)) { - Ln.v("DisplaySizeMonitor: onDisplayConfigurationChanged(" + eventDisplayId + ")"); + Ln.v("DisplayMonitor: onDisplayConfigurationChanged(" + eventDisplayId + ")"); } if (eventDisplayId == displayId) { - checkDisplaySizeChanged(); + checkDisplayPropertiesChanged(); } } }; @@ -97,38 +96,38 @@ public class DisplaySizeMonitor { } } - private synchronized Size getAndSetSessionDisplaySize(Size sessionDisplaySize) { - Size oldDisplaySize = this.sessionDisplaySize; - this.sessionDisplaySize = sessionDisplaySize; - return oldDisplaySize; + private synchronized DisplayProperties getAndSetDisplayProperties(DisplayProperties props) { + DisplayProperties oldProps = this.props; + this.props = props; + return oldProps; } - public synchronized void setSessionDisplaySize(Size sessionDisplaySize) { - this.sessionDisplaySize = sessionDisplaySize; + public synchronized void setSessionDisplayProperties(DisplayProperties props) { + this.props = props; } - private void checkDisplaySizeChanged() { + private void checkDisplayPropertiesChanged() { DisplayInfo di = ServiceManager.getDisplayManager().getDisplayInfo(displayId); if (di == null) { Ln.w("DisplayInfo for " + displayId + " cannot be retrieved"); - // We can't compare with the current size, so reset unconditionally - Size oldDisplaySize = getAndSetSessionDisplaySize(null); // exchange with synchronization + // We can't compare with the current properties, so reset unconditionally + DisplayProperties oldProps = getAndSetDisplayProperties(null); // exchange with synchronization if (Ln.isEnabled(Ln.Level.VERBOSE)) { - Ln.v("DisplaySizeMonitor: requestReset(): " + oldDisplaySize + " -> (unknown)"); + Ln.v("DisplayMonitor: requestReset(): " + oldProps + " -> (unknown)"); } - listener.onDisplaySizeChanged(); + listener.onDisplayPropertiesChanged(); } else { - Size size = di.getSize(); + DisplayProperties newProps = new DisplayProperties(di.getSize(), di.getRotation()); - Size oldDisplaySize = getAndSetSessionDisplaySize(size); // exchange with synchronization - if (!size.equals(oldDisplaySize)) { - // Reset only if the size is different + DisplayProperties oldProps = getAndSetDisplayProperties(newProps); // exchange with synchronization + if (!newProps.equals(oldProps)) { + // Reset only if the properties are different if (Ln.isEnabled(Ln.Level.VERBOSE)) { - Ln.v("DisplaySizeMonitor: requestReset(): " + oldDisplaySize + " -> " + size); + Ln.v("DisplayMonitor: requestReset(): " + oldProps + " -> " + newProps); } - listener.onDisplaySizeChanged(); + listener.onDisplayPropertiesChanged(); } else if (Ln.isEnabled(Ln.Level.VERBOSE)) { - Ln.v("DisplaySizeMonitor: Size not changed (" + size + "): do not requestReset()"); + Ln.v("DisplayMonitor: DisplayProperties not changed (" + newProps + "): do not requestReset()"); } } } diff --git a/server/src/main/java/com/genymobile/scrcpy/display/DisplayProperties.java b/server/src/main/java/com/genymobile/scrcpy/display/DisplayProperties.java new file mode 100644 index 00000000..d3658334 --- /dev/null +++ b/server/src/main/java/com/genymobile/scrcpy/display/DisplayProperties.java @@ -0,0 +1,52 @@ +package com.genymobile.scrcpy.display; + +import com.genymobile.scrcpy.model.Size; + +import java.util.Objects; + +public final class DisplayProperties { + private Size size; + private int rotation; + + public DisplayProperties(Size size, int rotation) { + assert size != null; + assert rotation >= 0 && rotation < 4; + this.size = size; + this.rotation = rotation; + } + + public Size getSize() { + return size; + } + + public void setSize(Size size) { + this.size = size; + } + + public int getRotation() { + return rotation; + } + + public void setRotation(int rotation) { + this.rotation = rotation; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + DisplayProperties that = (DisplayProperties) o; + return rotation == that.rotation && Objects.equals(size, that.size); + } + + @Override + public int hashCode() { + return Objects.hash(size, rotation); + } + + @Override + public String toString() { + return size + " [rotation=" + rotation + "]"; + } +} diff --git a/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java b/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java index ae728772..5608d131 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java @@ -4,7 +4,8 @@ import com.genymobile.scrcpy.AndroidVersions; import com.genymobile.scrcpy.Options; import com.genymobile.scrcpy.control.PositionMapper; import com.genymobile.scrcpy.display.DisplayInfo; -import com.genymobile.scrcpy.display.DisplaySizeMonitor; +import com.genymobile.scrcpy.display.DisplayMonitor; +import com.genymobile.scrcpy.display.DisplayProperties; import com.genymobile.scrcpy.model.NewDisplay; import com.genymobile.scrcpy.model.Orientation; import com.genymobile.scrcpy.model.Size; @@ -42,7 +43,7 @@ public class NewDisplayCapture extends SurfaceCapture { private final VirtualDisplayListener vdListener; private final NewDisplay newDisplay; - private final DisplaySizeMonitor displaySizeMonitor = new DisplaySizeMonitor(); + private final DisplayMonitor displayMonitor = new DisplayMonitor(); private AffineMatrix displayTransform; private AffineMatrix eventTransform; @@ -112,8 +113,8 @@ public class NewDisplayCapture extends SurfaceCapture { } displayRotation = 0; - // Set the current display size to avoid an unnecessary call to invalidate() - displaySizeMonitor.setSessionDisplaySize(displaySize); + // Set the current display properties to avoid an unnecessary call to invalidate() + displayMonitor.setSessionDisplayProperties(new DisplayProperties(displaySize, displayRotation)); } else { DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(virtualDisplay.getDisplay().getDisplayId()); displaySize = displayInfo.getSize(); @@ -194,7 +195,7 @@ public class NewDisplayCapture extends SurfaceCapture { ServiceManager.getWindowManager().setDisplayImePolicy(virtualDisplayId, displayImePolicy); } - displaySizeMonitor.start(virtualDisplayId, this::invalidate); + displayMonitor.start(virtualDisplayId, this::invalidate); } catch (Exception e) { Ln.e("Could not create display", e); throw new AssertionError("Could not create display"); @@ -232,7 +233,7 @@ public class NewDisplayCapture extends SurfaceCapture { @Override public void release() { - displaySizeMonitor.stopAndRelease(); + displayMonitor.stopAndRelease(); if (virtualDisplay != null) { virtualDisplay.release(); diff --git a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java index 77d2eb17..adabdfb0 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java @@ -5,7 +5,8 @@ import com.genymobile.scrcpy.Options; import com.genymobile.scrcpy.control.PositionMapper; import com.genymobile.scrcpy.device.Device; import com.genymobile.scrcpy.display.DisplayInfo; -import com.genymobile.scrcpy.display.DisplaySizeMonitor; +import com.genymobile.scrcpy.display.DisplayMonitor; +import com.genymobile.scrcpy.display.DisplayProperties; import com.genymobile.scrcpy.model.ConfigurationException; import com.genymobile.scrcpy.model.Orientation; import com.genymobile.scrcpy.model.Size; @@ -38,7 +39,7 @@ public class ScreenCapture extends SurfaceCapture { private DisplayInfo displayInfo; private Size videoSize; - private final DisplaySizeMonitor displaySizeMonitor = new DisplaySizeMonitor(); + private final DisplayMonitor displayMonitor = new DisplayMonitor(); private IBinder display; private VirtualDisplay virtualDisplay; @@ -60,7 +61,7 @@ public class ScreenCapture extends SurfaceCapture { @Override public void init() { - displaySizeMonitor.start(displayId, this::invalidate); + displayMonitor.start(displayId, this::invalidate); } @Override @@ -76,23 +77,24 @@ public class ScreenCapture extends SurfaceCapture { } Size displaySize = displayInfo.getSize(); - displaySizeMonitor.setSessionDisplaySize(displaySize); + int displayRotation = displayInfo.getRotation(); + displayMonitor.setSessionDisplayProperties(new DisplayProperties(displaySize, displayRotation)); if (captureOrientationLock == Orientation.Lock.LockedInitial) { // The user requested to lock the video orientation to the current orientation captureOrientationLock = Orientation.Lock.LockedValue; - captureOrientation = Orientation.fromRotation(displayInfo.getRotation()); + captureOrientation = Orientation.fromRotation(displayRotation); } VideoFilter filter = new VideoFilter(displaySize); if (crop != null) { - boolean transposed = (displayInfo.getRotation() % 2) != 0; + boolean transposed = (displayRotation % 2) != 0; filter.addCrop(crop, transposed); } boolean locked = captureOrientationLock != Orientation.Lock.Unlocked; - filter.addOrientation(displayInfo.getRotation(), locked, captureOrientation); + filter.addOrientation(displayRotation, locked, captureOrientation); filter.addAngle(angle); transform = filter.getInverseTransform(); @@ -169,7 +171,7 @@ public class ScreenCapture extends SurfaceCapture { @Override public void release() { - displaySizeMonitor.stopAndRelease(); + displayMonitor.stopAndRelease(); if (display != null) { SurfaceControl.destroyDisplay(display);