Merge "Make Glanceable Hub dimensions consistent between density changes." into main
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index ce28e80..fc95754 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -163,6 +163,8 @@
 import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
 import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.util.DensityUtils.Companion.adjustedDp
+import com.android.systemui.communal.util.DensityUtils.Companion.scalingAdjustment
 import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView
 import com.android.systemui.communal.widgets.WidgetConfigurator
 import com.android.systemui.res.R
@@ -649,11 +651,11 @@
     Card(
         modifier = Modifier.height(hubDimensions.GridHeight).padding(contentPadding),
         colors = CardDefaults.cardColors(containerColor = Color.Transparent),
-        border = BorderStroke(3.dp, colors.secondary),
-        shape = RoundedCornerShape(size = 80.dp)
+        border = BorderStroke(3.adjustedDp, colors.secondary),
+        shape = RoundedCornerShape(size = 80.adjustedDp)
     ) {
         Column(
-            modifier = Modifier.fillMaxSize().padding(horizontal = 110.dp),
+            modifier = Modifier.fillMaxSize().padding(horizontal = 110.adjustedDp),
             verticalArrangement =
                 Arrangement.spacedBy(Dimensions.Spacing, Alignment.CenterVertically),
             horizontalAlignment = Alignment.CenterHorizontally,
@@ -907,15 +909,15 @@
             // resize grid items to account for the border.
             modifier.drawBehind {
                 // 8dp of padding between the widget and the highlight on every side.
-                val padding = 8.dp.toPx()
+                val padding = 8.adjustedDp.toPx()
                 drawRoundRect(
                     brush,
                     alpha = alpha,
                     topLeft = Offset(-padding, -padding),
                     size =
                         Size(width = size.width + padding * 2, height = size.height + padding * 2),
-                    cornerRadius = CornerRadius(37.dp.toPx()),
-                    style = Stroke(width = 3.dp.toPx())
+                    cornerRadius = CornerRadius(37.adjustedDp.toPx()),
+                    style = Stroke(width = 3.adjustedDp.toPx())
                 )
             }
     )
@@ -935,7 +937,7 @@
                 containerColor = colors.primary,
                 contentColor = colors.onPrimary,
             ),
-        shape = RoundedCornerShape(68.dp, 34.dp, 68.dp, 34.dp)
+        shape = RoundedCornerShape(68.adjustedDp, 34.adjustedDp, 68.adjustedDp, 34.adjustedDp)
     ) {
         Column(
             modifier = Modifier.fillMaxSize().padding(vertical = 32.dp, horizontal = 50.dp),
@@ -1152,11 +1154,11 @@
         visible = visible,
         enter = fadeIn(),
         exit = fadeOut(),
-        modifier = modifier.padding(16.dp),
+        modifier = modifier.padding(16.adjustedDp),
     ) {
         FilledIconButton(
-            shape = RoundedCornerShape(16.dp),
-            modifier = Modifier.size(48.dp),
+            shape = RoundedCornerShape(16.adjustedDp),
+            modifier = Modifier.size(48.adjustedDp),
             colors =
                 IconButtonColors(
                     containerColor = colors.primary,
@@ -1169,7 +1171,7 @@
             Icon(
                 imageVector = Icons.Outlined.Edit,
                 contentDescription = stringResource(id = R.string.edit_widget),
-                modifier = Modifier.padding(12.dp)
+                modifier = Modifier.padding(12.adjustedDp)
             )
         }
     }
@@ -1232,7 +1234,9 @@
         modifier =
             modifier.background(
                 MaterialTheme.colorScheme.surfaceVariant,
-                RoundedCornerShape(dimensionResource(system_app_widget_background_radius))
+                RoundedCornerShape(
+                    dimensionResource(system_app_widget_background_radius) * scalingAdjustment
+                )
             ),
         verticalArrangement = Arrangement.Center,
         horizontalAlignment = Alignment.CenterHorizontally,
@@ -1413,11 +1417,11 @@
     val GridTopSpacing: Dp
         get() {
             if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
-                return 114.dp
+                return 114.adjustedDp
             } else {
                 val windowMetrics =
                     WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
-                val screenHeight = with(density) { windowMetrics.bounds.height().toDp() }
+                val screenHeight = with(density) { windowMetrics.bounds.height().adjustedDp }
 
                 return (screenHeight - CardHeightFull) / 2
             }
@@ -1426,26 +1430,47 @@
     val GridHeight = CardHeightFull + GridTopSpacing
 
     companion object {
-        val CardHeightFull = 530.dp
-        val ItemSpacing = 50.dp
-        val CardHeightHalf = (CardHeightFull - ItemSpacing) / 2
-        val CardHeightThird = (CardHeightFull - (2 * ItemSpacing)) / 3
-        val CardWidth = 360.dp
-        val CardOutlineWidth = 3.dp
-        val Spacing = ItemSpacing / 2
+        val CardHeightFull
+            get() = 530.adjustedDp
+
+        val ItemSpacing
+            get() = 50.adjustedDp
+
+        val CardHeightHalf
+            get() = (CardHeightFull - ItemSpacing) / 2
+
+        val CardHeightThird
+            get() = (CardHeightFull - (2 * ItemSpacing)) / 3
+
+        val CardWidth
+            get() = 360.adjustedDp
+
+        val CardOutlineWidth
+            get() = 3.adjustedDp
+
+        val Spacing
+            get() = ItemSpacing / 2
 
         // The sizing/padding of the toolbar in glanceable hub edit mode
-        val ToolbarPaddingTop = 27.dp
-        val ToolbarPaddingHorizontal = ItemSpacing
-        val ToolbarButtonPaddingHorizontal = 24.dp
-        val ToolbarButtonPaddingVertical = 16.dp
+        val ToolbarPaddingTop
+            get() = 27.adjustedDp
+
+        val ToolbarPaddingHorizontal
+            get() = ItemSpacing
+
+        val ToolbarButtonPaddingHorizontal
+            get() = 24.adjustedDp
+
+        val ToolbarButtonPaddingVertical
+            get() = 16.adjustedDp
+
         val ButtonPadding =
             PaddingValues(
                 vertical = ToolbarButtonPaddingVertical,
                 horizontal = ToolbarButtonPaddingHorizontal,
             )
-        val IconSize = 40.dp
-        val SlideOffsetY = 30.dp
+        val IconSize = 40.adjustedDp
+        val SlideOffsetY = 30.adjustedDp
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/DensityUtils.kt b/packages/SystemUI/src/com/android/systemui/communal/util/DensityUtils.kt
new file mode 100644
index 0000000..57be7b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/DensityUtils.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.communal.util
+
+import android.view.Display
+import android.view.WindowManagerGlobal
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+
+/**
+ * [DensityUtils] helps convert dp defined values to be consistent regardless of the set density.
+ */
+class DensityUtils {
+    companion object {
+        val Int.adjustedDp: Dp
+            get() = this.dp * scalingAdjustment
+
+        private val windowManagerService = WindowManagerGlobal.getWindowManagerService()
+        val scalingAdjustment
+            get() =
+                windowManagerService?.let { wm ->
+                    wm.getInitialDisplayDensity(Display.DEFAULT_DISPLAY).toFloat() /
+                        wm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY)
+                } ?: 1F
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/RoundedCornerEnforcement.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/RoundedCornerEnforcement.kt
index abda44b..87aa5e2 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/RoundedCornerEnforcement.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/RoundedCornerEnforcement.kt
@@ -24,6 +24,7 @@
 import android.view.View
 import android.view.ViewGroup
 import androidx.core.os.BuildCompat.isAtLeastS
+import com.android.systemui.communal.util.DensityUtils
 import com.android.systemui.res.R
 import kotlin.math.min
 
@@ -82,7 +83,8 @@
     /** Get the radius of the rounded rectangle defined in the host's resource. */
     private fun getOwnedEnforcedRadius(context: Context): Float {
         val res: Resources = context.resources
-        return res.getDimension(R.dimen.communal_enforced_rounded_corner_max_radius)
+        return res.getDimension(R.dimen.communal_enforced_rounded_corner_max_radius) *
+            DensityUtils.scalingAdjustment
     }
 
     /**