Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acf3f58c authored by Ebru Kurnaz's avatar Ebru Kurnaz
Browse files

Move calculating base density for external displays to LogicalDisplay.

This is needed for the upcoming synthetic mode resolution change that will override the resolution in LogicalDisplay.
Having density calculation in LogicalDisplay solves the density update issue on resolution change.

Bug: 438485020
Test: atest LogicalDisplayTest
Flag: com.android.server.display.feature.flags.base_density_for_external_displays
Change-Id: I799332ecfb5ef9f83e239d75e1ba82d0a2bd73f7
parent ca2cb1ed
Loading
Loading
Loading
Loading
+3 −27
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ import android.os.PowerManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.util.DisplayMetrics;
import android.util.DisplayUtils;
import android.util.LongSparseArray;
import android.util.Slog;
@@ -85,13 +84,6 @@ final class LocalDisplayAdapter extends DisplayAdapter {

    private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.boot.emulator.circular";

    private static final double DEFAULT_DISPLAY_SIZE = 24.0;
    // Touch target size 10.4mm in inches (divided by mm per inch 25.4)
    private static final double EXTERNAL_DISPLAY_BASE_TOUCH_TARGET_SIZE_IN_INCHES = 10.4 / 25.4;
    private static final int EXTERNAL_DISPLAY_MIN_DENSITY_DPI = 100;

    private static final double BASE_TOUCH_TARGET_SIZE_DP = 48.0;

    private final LongSparseArray<LocalDisplayDevice> mDevices = new LongSparseArray<>();

    private final Injector mInjector;
@@ -539,25 +531,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
            if (densityMapping == null) {
                if (getFeatureFlags().isBaseDensityForExternalDisplaysEnabled()
                        && !mStaticDisplayInfo.isInternal) {
                    double ppi;

                    if (mActiveSfDisplayMode.xDpi > 0 && mActiveSfDisplayMode.yDpi > 0) {
                        ppi = Math.sqrt((Math.pow(mActiveSfDisplayMode.xDpi, 2)
                                + Math.pow(mActiveSfDisplayMode.yDpi, 2)) / 2);
                    } else {
                        // xDPI and yDPI is missing, calculate DPI from display resolution and
                        // default display size
                        ppi = Math.sqrt(Math.pow(mInfo.width, 2) + Math.pow(mInfo.height, 2))
                                / DEFAULT_DISPLAY_SIZE;
                    }
                    double pixels = ppi * EXTERNAL_DISPLAY_BASE_TOUCH_TARGET_SIZE_IN_INCHES;
                    double dpi =
                            pixels * DisplayMetrics.DENSITY_DEFAULT / BASE_TOUCH_TARGET_SIZE_DP;
                    if (dpi < EXTERNAL_DISPLAY_MIN_DENSITY_DPI) {
                        return EXTERNAL_DISPLAY_MIN_DENSITY_DPI;
                    } else {
                        return (int) (dpi + 0.5);
                    }
                    // Return 0 for external displays as the base density will be calculated in
                    // the LogicalDisplay.
                    return 0;
                }
                return (int) (mStaticDisplayInfo.density * 160 + 0.5);
            }
+31 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManagerInternal;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayEventReceiver;
@@ -78,6 +79,13 @@ final class LogicalDisplay {

    private static final DisplayInfo EMPTY_DISPLAY_INFO = new DisplayInfo();

    private static final double DEFAULT_DISPLAY_SIZE = 24.0;
    // Touch target size 10.4mm in inches (divided by mm per inch 25.4)
    private static final double EXTERNAL_DISPLAY_BASE_TOUCH_TARGET_SIZE_IN_INCHES = 10.4 / 25.4;
    private static final int EXTERNAL_DISPLAY_MIN_DENSITY_DPI = 100;

    private static final double BASE_TOUCH_TARGET_SIZE_DP = 48.0;

    private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();
    private final int mDisplayId;
    private final int mLayerStack;
@@ -539,7 +547,10 @@ final class LogicalDisplay {
            mBaseDisplayInfo.userDisabledHdrTypes = mUserDisabledHdrTypes;
            mBaseDisplayInfo.minimalPostProcessingSupported =
                    deviceInfo.allmSupported || deviceInfo.gameContentTypeSupported;
            mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
            mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi > 0
                    ? deviceInfo.densityDpi
                    : calculateBaseDensity(deviceInfo.xDpi, deviceInfo.yDpi, maskedWidth,
                            maskedHeight);
            mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
            mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
            mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
@@ -589,6 +600,25 @@ final class LogicalDisplay {
        }
    }

    private int calculateBaseDensity(float xDpi, float yDpi, int width, int height) {
        // physical pixel density of the display
        double ppi;
        if (xDpi > 0 && yDpi > 0) {
            ppi = Math.sqrt((Math.pow(xDpi, 2)
                    + Math.pow(yDpi, 2)) / 2);
        } else {
            // xDPI and yDPI is missing, calculate DPI from display resolution and
            // default display size
            ppi = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2))
                    / DEFAULT_DISPLAY_SIZE;
        }
        // pixels needed to achieve target touch target size
        double pixels = ppi * EXTERNAL_DISPLAY_BASE_TOUCH_TARGET_SIZE_IN_INCHES;
        double dpi =
                pixels * DisplayMetrics.DENSITY_DEFAULT / BASE_TOUCH_TARGET_SIZE_DP;
        return Math.max((int) (dpi + 0.5), EXTERNAL_DISPLAY_MIN_DENSITY_DPI);
    }

    private void updateFrameRateOverrides(DisplayDeviceInfo deviceInfo) {
        mTempFrameRateOverride.clear();
        if (mFrameRateOverrides != null) {
+2 −2
Original line number Diff line number Diff line
@@ -555,10 +555,10 @@ public class LocalDisplayAdapterTest {

        assertDisplayDpi(
                mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), PORT_A, 100, 100,
                136);
                0);
        assertDisplayDpi(
                mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), PORT_B, 100, 100,
                136);
                0);
    }

    private static class DisplayModeWrapper {
+63 −0
Original line number Diff line number Diff line
@@ -675,4 +675,67 @@ public class LogicalDisplayTest {
        mLogicalDisplay.setCanHostTasksLocked(false);
        assertTrue(mLogicalDisplay.canHostTasksLocked());
    }

    @Test
    public void testCalculateBaseDensity_withValidDpi() {
        mLogicalDisplay =
                new LogicalDisplay(Display.DEFAULT_DISPLAY + 1, LAYER_STACK, mDisplayDevice);
        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
        mDisplayDeviceInfo.densityDpi = 0; // To trigger calculateBaseDensity
        mDisplayDeviceInfo.xDpi = 100f;
        mDisplayDeviceInfo.yDpi = 100f;
        mDisplayDeviceInfo.width = 1920;
        mDisplayDeviceInfo.height = 1080;

        mLogicalDisplay.updateLocked(mDeviceRepo, mSyntheticModeManager);
        DisplayInfo info = mLogicalDisplay.getDisplayInfoLocked();

        assertEquals(136, info.logicalDensityDpi);
    }

    @Test
    public void testCalculateBaseDensity_withValidDpi_usesMinimumDensityDpi() {
        mLogicalDisplay =
                new LogicalDisplay(Display.DEFAULT_DISPLAY + 1, LAYER_STACK, mDisplayDevice);
        mDisplayDeviceInfo.densityDpi = 0; // To trigger calculateBaseDensity
        mDisplayDeviceInfo.xDpi = 50f;
        mDisplayDeviceInfo.yDpi = 50f;
        mDisplayDeviceInfo.width = 1920;
        mDisplayDeviceInfo.height = 1080;

        mLogicalDisplay.updateLocked(mDeviceRepo, mSyntheticModeManager);
        DisplayInfo info = mLogicalDisplay.getDisplayInfoLocked();

        assertEquals(100, info.logicalDensityDpi);
    }

    @Test
    public void testCalculateBaseDensity_notCalledWhenDensityDpiIsSet() {
        mLogicalDisplay =
                new LogicalDisplay(Display.DEFAULT_DISPLAY + 1, LAYER_STACK, mDisplayDevice);
        mDisplayDeviceInfo.densityDpi = 320;
        mDisplayDeviceInfo.xDpi = 100f;
        mDisplayDeviceInfo.yDpi = 100f;

        mLogicalDisplay.updateLocked(mDeviceRepo, mSyntheticModeManager);
        DisplayInfo info = mLogicalDisplay.getDisplayInfoLocked();

        assertEquals(320, info.logicalDensityDpi);
    }

    @Test
    public void testCalculateBaseDensity_withMissingDpi() {
        mLogicalDisplay =
                new LogicalDisplay(Display.DEFAULT_DISPLAY + 1, LAYER_STACK, mDisplayDevice);
        mDisplayDeviceInfo.densityDpi = 0;
        mDisplayDeviceInfo.xDpi = 0f;
        mDisplayDeviceInfo.yDpi = 0f;
        mDisplayDeviceInfo.width = 1920;
        mDisplayDeviceInfo.height = 1080;

        mLogicalDisplay.updateLocked(mDeviceRepo, mSyntheticModeManager);
        DisplayInfo info = mLogicalDisplay.getDisplayInfoLocked();

        assertEquals(125, info.logicalDensityDpi);
    }
}