From 2d0ca1a195a3d3612345ec9894b1a938ea2fc881 Mon Sep 17 00:00:00 2001 From: Toni Barzic Date: Wed, 4 Jun 2025 22:54:57 +0000 Subject: [PATCH] Move logic for stable scale factor to DisplayController When selecting grid size to use for desktop, size breakpoints are compared to the display dimensions with "stable" device density. Expose the scale factor that needs to be applied to dimensions provided in spec via DisplayController::Info, so it can be more easily faked in tests. Bug: 375643744 Test: atest DeviceProfileDumpTest Flag: com.android.launcher3.enable_scalability_for_desktop_experience Change-Id: I836430cc052f72c0f89b6cdd5ab5309a3482d94e --- .../quickstep/util/TaskViewSimulatorTest.java | 2 +- .../OrientationTouchTransformerTest.java | 3 +- .../launcher3/InvariantDeviceProfile.java | 31 ++++++++++------- .../launcher3/util/DisplayController.java | 21 +++++++++--- .../launcher3/AbstractDeviceProfileTest.kt | 33 ++++++++++++++++++- 5 files changed, 70 insertions(+), 20 deletions(-) diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java index 190a5b2d10..060f13f1e2 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java @@ -202,7 +202,7 @@ public class TaskViewSimulatorTest { Context configurationContext = app.createConfigurationContext(configuration); DisplayController.Info info = new Info( - configurationContext, false, wmProxy, perDisplayBoundsCache); + configurationContext, false, wmProxy, perDisplayBoundsCache, mDensityDpi); when(mockController.getInfo()).thenReturn(info); mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(app) diff --git a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java index 82408aa5b8..cd8dd6e00c 100644 --- a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java +++ b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java @@ -339,7 +339,8 @@ public class OrientationTouchTransformerTest { ArrayMap> internalDisplayBounds = new ArrayMap<>(); doReturn(internalDisplayBounds).when(wmProxy).estimateInternalDisplayBounds(any()); return new DisplayController.Info( - getApplicationContext(), false, wmProxy, new ArrayMap<>()); + getApplicationContext(), false, wmProxy, new ArrayMap<>(), + DisplayMetrics.DENSITY_DEFAULT); } private float generateTouchRegionHeight(Size screenSize, int rotation) { diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 53c8bf11de..7b186f930c 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -635,6 +635,10 @@ public class InvariantDeviceProfile { // the change in display size changes the grid size. boolean matchAgainstDefaultDpSize = displayInfo.getDeviceType() == TYPE_DESKTOP && enableScalabilityForDesktopExperience(); + float stableDensityScale = + matchAgainstDefaultDpSize + ? displayInfo.getStableDensityScaleFactor() : 1.0f; + try (XmlResourceParser parser = resourceHelper.getXml()) { final int depth = parser.getDepth(); int type; @@ -643,7 +647,7 @@ public class InvariantDeviceProfile { if ((type == XmlPullParser.START_TAG) && "GridSize".equals(parser.getName())) { gridSizes.add(new GridSize(context, Xml.asAttributeSet(parser), - matchAgainstDefaultDpSize)); + stableDensityScale)); } } } catch (IOException | XmlPullParserException e) { @@ -660,6 +664,12 @@ public class InvariantDeviceProfile { Info displayInfo) { ArrayList allAppsSizes = new ArrayList<>(); + boolean matchAgainstDefaultDpSize = displayInfo.getDeviceType() == TYPE_DESKTOP + && enableScalabilityForDesktopExperience(); + float stableDensityScale = + matchAgainstDefaultDpSize + ? displayInfo.getStableDensityScaleFactor() : 1.0f; + try (XmlResourceParser parser = resourceHelper.getXml()) { final int depth = parser.getDepth(); int type; @@ -667,7 +677,8 @@ public class InvariantDeviceProfile { || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { if ((type == XmlPullParser.START_TAG) && "AllAppsSize".equals(parser.getName())) { - allAppsSizes.add(new AllAppsSize(context, Xml.asAttributeSet(parser))); + allAppsSizes.add(new AllAppsSize(context, Xml.asAttributeSet(parser), + stableDensityScale)); } } } catch (IOException | XmlPullParserException e) { @@ -1352,20 +1363,16 @@ public class InvariantDeviceProfile { final String mDbFile; final int mDefaultLayoutId; - GridSize(Context context, AttributeSet attrs, boolean matchAgainstDefaultDpSize) { + GridSize(Context context, AttributeSet attrs, float stableDensityScale) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridSize); mNumRows = (int) a.getFloat(R.styleable.GridSize_numGridRows, 0); mNumColumns = (int) a.getFloat(R.styleable.GridSize_numGridColumns, 0); - float defaultScale = - matchAgainstDefaultDpSize - ? (float) DisplayMetrics.DENSITY_DEVICE_STABLE - / DisplayMetrics.DENSITY_DEFAULT - : 1.0f; - mMinDeviceWidthPx = a.getInt(R.styleable.GridSize_minDeviceWidthPx, 0) * defaultScale; + mMinDeviceWidthPx = a.getInt(R.styleable.GridSize_minDeviceWidthPx, 0) + * stableDensityScale; mMinDeviceHeightPx = a.getInt(R.styleable.GridSize_minDeviceHeightPx, 0) - * defaultScale; + * stableDensityScale; mDbFile = a.getString(R.styleable.GridSize_dbFile); mDefaultLayoutId = a.getResourceId( @@ -1389,12 +1396,12 @@ public class InvariantDeviceProfile { // The minimum device pixel width to which the spec can be applied. final float mMinDeviceWidthPx; - AllAppsSize(Context context, AttributeSet attrs) { + AllAppsSize(Context context, AttributeSet attrs, float stableDensityScale) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AllAppsSize); mAlignWithWorkspaceRow = a.getInt(R.styleable.AllAppsSize_alignWithWorkspaceRow, -1); mMinDeviceWidthPx = a.getFloat(R.styleable.AllAppsSize_minDeviceWidthDp, 0) - * DisplayMetrics.DENSITY_DEVICE_STABLE / DisplayMetrics.DENSITY_DEFAULT; + * stableDensityScale; a.recycle(); } diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java index ba5c996ee3..60c65e586b 100644 --- a/src/com/android/launcher3/util/DisplayController.java +++ b/src/com/android/launcher3/util/DisplayController.java @@ -42,6 +42,7 @@ import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.DisplayMetrics; import android.util.Log; import android.util.SparseArray; import android.view.Display; @@ -435,13 +436,14 @@ public class DisplayController implements DesktopVisibilityListener { private Info getNewInfo(Info oldInfo, Context displayInfoContext) { Info newInfo = new Info(displayInfoContext, mIsDesktopFormFactor, mWMProxy, - oldInfo.mPerDisplayBounds); + oldInfo.mPerDisplayBounds, DisplayMetrics.DENSITY_DEVICE_STABLE); if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale || newInfo.getNavigationMode() != oldInfo.getNavigationMode()) { // Cache may not be valid anymore, recreate without cache newInfo = new Info(displayInfoContext, mIsDesktopFormFactor, mWMProxy, - mWMProxy.estimateInternalDisplayBounds(displayInfoContext)); + mWMProxy.estimateInternalDisplayBounds(displayInfoContext), + DisplayMetrics.DENSITY_DEVICE_STABLE); } return newInfo; } @@ -479,7 +481,8 @@ public class DisplayController implements DesktopVisibilityListener { } Context windowContext = mAppContext.createWindowContext(display, TYPE_APPLICATION, null); Info info = new Info(windowContext, mIsDesktopFormFactor, mWMProxy, - mWMProxy.estimateInternalDisplayBounds(windowContext)); + mWMProxy.estimateInternalDisplayBounds(windowContext), + DisplayMetrics.DENSITY_DEVICE_STABLE); perDisplayInfo = new PerDisplayInfo(displayId, windowContext, info); mPerDisplayInfo.put(displayId, perDisplayInfo); return perDisplayInfo; @@ -508,6 +511,7 @@ public class DisplayController implements DesktopVisibilityListener { // Configuration property public final float fontScale; private final int densityDpi; + private final float mStableDensityScaleFactor; private final NavigationMode navigationMode; private final PortraitSize mScreenSizeDp; @@ -534,14 +538,16 @@ public class DisplayController implements DesktopVisibilityListener { this(displayInfoContext, enableScalabilityForDesktopExperience() && displayInfoContext.getResources().getBoolean( R.bool.desktop_form_factor), - new WindowManagerProxy(), new ArrayMap<>()); + new WindowManagerProxy(), new ArrayMap<>(), + DisplayMetrics.DENSITY_DEVICE_STABLE); } // Used for testing public Info(Context displayInfoContext, boolean isDesktopFormFactor, WindowManagerProxy wmProxy, - Map> perDisplayBoundsCache) { + Map> perDisplayBoundsCache, + int defaultDensityDpi) { CachedDisplayInfo displayInfo = wmProxy.getDisplayInfo(displayInfoContext); normalizedDisplayInfo = displayInfo.normalize(wmProxy); rotation = displayInfo.rotation; @@ -551,6 +557,7 @@ public class DisplayController implements DesktopVisibilityListener { Configuration config = displayInfoContext.getResources().getConfiguration(); fontScale = config.fontScale; densityDpi = config.densityDpi; + mStableDensityScaleFactor = (float) defaultDensityDpi / DisplayMetrics.DENSITY_DEFAULT; mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp); navigationMode = wmProxy.getNavigationMode(displayInfoContext); mIsNightModeActive = config.isNightModeActive(); @@ -681,6 +688,10 @@ public class DisplayController implements DesktopVisibilityListener { return densityDpi; } + public float getStableDensityScaleFactor() { + return mStableDensityScaleFactor; + } + public @DeviceType int getDeviceType() { if (mIsDesktopFormFactor) { return TYPE_DESKTOP; diff --git a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt index 65d55e203f..d25bfeda6a 100644 --- a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt @@ -173,6 +173,28 @@ abstract class AbstractDeviceProfileTest { ) } + protected fun initializeVarsForDesktop( + deviceSpec: DeviceSpec, + isLandscape: Boolean = false, + isGestureMode: Boolean = true, + gridName: String? = GRID_NAME.defaultValue, + ) { + val (naturalX, naturalY) = deviceSpec.naturalSize + val windowsBounds = tabletWindowsBounds(deviceSpec, naturalX, naturalY) + val displayInfo = CachedDisplayInfo(Point(naturalX, naturalY), Surface.ROTATION_0) + val perDisplayBoundsCache = mapOf(displayInfo to windowsBounds) + + initializeCommonVars( + perDisplayBoundsCache, + displayInfo, + rotation = if (isLandscape) Surface.ROTATION_0 else Surface.ROTATION_90, + isGestureMode, + densityDpi = deviceSpec.densityDpi, + gridName = gridName, + isDesktopFormFactor = true, + ) + } + protected fun initializeVarsForTwoPanel( deviceSpecUnfolded: DeviceSpec, deviceSpecFolded: DeviceSpec, @@ -291,6 +313,7 @@ abstract class AbstractDeviceProfileTest { isGestureMode: Boolean = true, densityDpi: Int, isFixedLandscape: Boolean = false, + isDesktopFormFactor: Boolean = false, gridName: String? = GRID_NAME.defaultValue, ) { setFlagsRule.setFlags(true, Flags.FLAG_ENABLE_TWOLINE_TOGGLE) @@ -341,7 +364,15 @@ abstract class AbstractDeviceProfileTest { } val info = - spy(DisplayController.Info(context, false, windowManagerProxy, perDisplayBoundsCache)) + spy( + DisplayController.Info( + context, + isDesktopFormFactor, + windowManagerProxy, + perDisplayBoundsCache, + densityDpi, + ) + ) whenever(displayController.info).thenReturn(info) whenever(info.isTransientTaskbar).thenReturn(isGestureMode) }