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

Commit 1e379cb5 authored by Piotr Wilczyński's avatar Piotr Wilczyński Committed by Android (Google) Code Review
Browse files

Merge "Display topology util methods" into main

parents 8bd6ab3a 57cc5cd1
Loading
Loading
Loading
Loading
+55 −9
Original line number Diff line number Diff line
@@ -27,10 +27,12 @@ import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.DisplayMetrics;
import android.util.IndentingPrintWriter;
import android.util.MathUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;

import androidx.annotation.NonNull;
@@ -74,6 +76,24 @@ public final class DisplayTopology implements Parcelable {
                }
            };

    /**
     * @param px The value in logical pixels
     * @param dpi The logical density of the display
     * @return The value in density-independent pixels
     */
    public static float pxToDp(float px, int dpi) {
        return px * DisplayMetrics.DENSITY_DEFAULT / dpi;
    }

    /**
     * @param dp The value in density-independent pixels
     * @param dpi The logical density of the display
     * @return The value in logical pixels
     */
    public static float dpToPx(float dp, int dpi) {
        return dp * dpi / DisplayMetrics.DENSITY_DEFAULT;
    }

    /**
     * The topology tree
     */
@@ -474,6 +494,22 @@ public final class DisplayTopology implements Parcelable {
        return new DisplayTopology(rootCopy, mPrimaryDisplayId);
    }

    /**
     * Assign absolute bounds to each display. The top-left corner of the root is at position
     * (0, 0).
     * @return Map from logical display ID to the display's absolute bounds
     */
    public SparseArray<RectF> getAbsoluteBounds() {
        Map<TreeNode, RectF> bounds = new HashMap<>();
        getInfo(bounds, /* depths= */ null, /* parents= */ null, mRoot, /* x= */ 0, /* y= */ 0,
                /* depth= */ 0);
        SparseArray<RectF> boundsById = new SparseArray<>();
        for (Map.Entry<TreeNode, RectF> entry : bounds.entrySet()) {
            boundsById.append(entry.getKey().mDisplayId, entry.getValue());
        }
        return boundsById;
    }

    @Override
    public int describeContents() {
        return 0;
@@ -575,7 +611,7 @@ public final class DisplayTopology implements Parcelable {
    }

    @Nullable
    private static TreeNode findDisplay(int displayId, TreeNode startingNode) {
    private static TreeNode findDisplay(int displayId, @Nullable TreeNode startingNode) {
        if (startingNode == null) {
            return null;
        }
@@ -592,8 +628,8 @@ public final class DisplayTopology implements Parcelable {
    }

    /**
     * Get information about the topology that will be used for the normalization algorithm.
     * Assigns origins to each display to compute the bounds.
     * Get information about the topology.
     * Assigns positions to each display to compute the bounds. The root is at position (0, 0).
     * @param bounds The map where the bounds of each display will be put
     * @param depths The map where the depths of each display in the tree will be put
     * @param parents The map where the parent of each display will be put
@@ -602,12 +638,22 @@ public final class DisplayTopology implements Parcelable {
     * @param y The starting y position
     * @param depth The starting depth
     */
    private static void getInfo(Map<TreeNode, RectF> bounds, Map<TreeNode, Integer> depths,
            Map<TreeNode, TreeNode> parents, TreeNode display, float x, float y, int depth) {
    private static void getInfo(@Nullable Map<TreeNode, RectF> bounds,
            @Nullable Map<TreeNode, Integer> depths, @Nullable Map<TreeNode, TreeNode> parents,
            @Nullable TreeNode display, float x, float y, int depth) {
        if (display == null) {
            return;
        }
        if (bounds != null) {
            bounds.put(display, new RectF(x, y, x + display.mWidth, y + display.mHeight));
        }
        if (depths != null) {
            depths.put(display, depth);
        }
        for (TreeNode child : display.mChildren) {
            if (parents != null) {
                parents.put(child, display);
            }
            if (child.mPosition == POSITION_LEFT) {
                getInfo(bounds, depths, parents, child, x - child.mWidth, y + child.mOffset,
                        depth + 1);
@@ -662,7 +708,7 @@ public final class DisplayTopology implements Parcelable {
     * Ensure that the offsets of all displays within the given tree are within bounds.
     * @param display The starting node
     */
    private void clampOffsets(TreeNode display) {
    private void clampOffsets(@Nullable TreeNode display) {
        if (display == null) {
            return;
        }
+29 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.hardware.display.DisplayTopology.TreeNode.POSITION_BOTTOM
import android.hardware.display.DisplayTopology.TreeNode.POSITION_LEFT
import android.hardware.display.DisplayTopology.TreeNode.POSITION_TOP
import android.hardware.display.DisplayTopology.TreeNode.POSITION_RIGHT
import android.util.SparseArray
import android.view.Display
import com.google.common.truth.Truth.assertThat
import org.junit.Test
@@ -687,6 +688,34 @@ class DisplayTopologyTest {
            offset = 0f, noOfChildren = 0)
    }

    @Test
    fun coordinates() {
        val display1 = DisplayTopology.TreeNode(/* displayId= */ 1, /* width= */ 200f,
            /* height= */ 600f, /* position= */ 0, /* offset= */ 0f)

        val display2 = DisplayTopology.TreeNode(/* displayId= */ 2, /* width= */ 600f,
            /* height= */ 200f, POSITION_RIGHT, /* offset= */ 0f)
        display1.addChild(display2)

        val display3 = DisplayTopology.TreeNode(/* displayId= */ 3, /* width= */ 600f,
            /* height= */ 200f, POSITION_RIGHT, /* offset= */ 400f)
        display1.addChild(display3)

        val display4 = DisplayTopology.TreeNode(/* displayId= */ 4, /* width= */ 200f,
            /* height= */ 600f, POSITION_RIGHT, /* offset= */ 0f)
        display2.addChild(display4)

        topology = DisplayTopology(display1, /* primaryDisplayId= */ 1)
        val coords = topology.absoluteBounds

        val expectedCoords = SparseArray<RectF>()
        expectedCoords.append(1, RectF(0f, 0f, 200f, 600f))
        expectedCoords.append(2, RectF(200f, 0f, 800f, 200f))
        expectedCoords.append(3, RectF(200f, 400f, 800f, 600f))
        expectedCoords.append(4, RectF(800f, 0f, 1000f, 600f))
        assertThat(coords.contentEquals(expectedCoords)).isTrue()
    }

    /**
     * Runs the rearrange algorithm and returns the resulting tree as a list of nodes, with the
     * root at index 0. The number of nodes is inferred from the number of positions passed.
+4 −5
Original line number Diff line number Diff line
@@ -16,8 +16,9 @@

package com.android.server.display;

import static android.hardware.display.DisplayTopology.pxToDp;

import android.hardware.display.DisplayTopology;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.DisplayInfo;

@@ -140,8 +141,7 @@ class DisplayTopologyCoordinator {
     * @return The width of the display in dp
     */
    private float getWidth(DisplayInfo info) {
        return info.logicalWidth * (float) DisplayMetrics.DENSITY_DEFAULT
                / info.logicalDensityDpi;
        return pxToDp(info.logicalWidth, info.logicalDensityDpi);
    }

    /**
@@ -149,8 +149,7 @@ class DisplayTopologyCoordinator {
     * @return The height of the display in dp
     */
    private float getHeight(DisplayInfo info) {
        return info.logicalHeight * (float) DisplayMetrics.DENSITY_DEFAULT
                / info.logicalDensityDpi;
        return pxToDp(info.logicalHeight, info.logicalDensityDpi);
    }

    private boolean isDisplayAllowedInTopology(DisplayInfo info) {
+3 −5
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
package com.android.server.display

import android.hardware.display.DisplayTopology
import android.util.DisplayMetrics
import android.hardware.display.DisplayTopology.pxToDp
import android.view.Display
import android.view.DisplayInfo
import com.google.common.truth.Truth.assertThat
@@ -62,10 +62,8 @@ class DisplayTopologyCoordinatorTest {
    fun addDisplay() {
        coordinator.onDisplayAdded(displayInfo)

        val widthDp = displayInfo.logicalWidth * (DisplayMetrics.DENSITY_DEFAULT.toFloat()
                / displayInfo.logicalDensityDpi)
        val heightDp = displayInfo.logicalHeight * (DisplayMetrics.DENSITY_DEFAULT.toFloat()
                / displayInfo.logicalDensityDpi)
        val widthDp = pxToDp(displayInfo.logicalWidth.toFloat(), displayInfo.logicalDensityDpi)
        val heightDp = pxToDp(displayInfo.logicalHeight.toFloat(), displayInfo.logicalDensityDpi)
        verify(mockTopology).addDisplay(displayInfo.displayId, widthDp, heightDp)
        verify(mockTopologyChangedCallback).invoke(mockTopologyCopy)
    }