Merge "[flexiglass] Introduces use of alignment lines." into main
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BlueprintAlignmentLines.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BlueprintAlignmentLines.kt
new file mode 100644
index 0000000..efa8cc7
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BlueprintAlignmentLines.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 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.keyguard.ui.composable.blueprint
+
+import androidx.compose.ui.layout.HorizontalAlignmentLine
+import androidx.compose.ui.layout.VerticalAlignmentLine
+import kotlin.math.max
+import kotlin.math.min
+
+/**
+ * Encapsulates all blueprint alignment lines.
+ *
+ * These can be used to communicate alignment lines emitted by elements that the blueprint should
+ * consume and use to know how to constrain and/or place other elements in that blueprint.
+ *
+ * For more information, please see
+ * [the official documentation](https://developer.android.com/jetpack/compose/layouts/alignment-lines).
+ */
+object BlueprintAlignmentLines {
+
+ /**
+ * Encapsulates alignment lines produced by the lock icon element.
+ *
+ * Because the lock icon is also the same element as the under-display fingerprint sensor
+ * (UDFPS), blueprints should use its alignment lines to make sure that other elements on screen
+ * do not overlap with the lock icon.
+ */
+ object LockIcon {
+
+ /** The left edge of the lock icon. */
+ val Left =
+ VerticalAlignmentLine(
+ merger = { old, new ->
+ // When two left alignment line values are provided, choose the leftmost one:
+ min(old, new)
+ },
+ )
+
+ /** The top edge of the lock icon. */
+ val Top =
+ HorizontalAlignmentLine(
+ merger = { old, new ->
+ // When two top alignment line values are provided, choose the topmost one:
+ min(old, new)
+ },
+ )
+
+ /** The right edge of the lock icon. */
+ val Right =
+ VerticalAlignmentLine(
+ merger = { old, new ->
+ // When two right alignment line values are provided, choose the rightmost one:
+ max(old, new)
+ },
+ )
+
+ /** The bottom edge of the lock icon. */
+ val Bottom =
+ HorizontalAlignmentLine(
+ merger = { old, new ->
+ // When two bottom alignment line values are provided, choose the bottommost
+ // one:
+ max(old, new)
+ },
+ )
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
index fc1df84..7314453 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
@@ -16,18 +16,13 @@
package com.android.systemui.keyguard.ui.composable.blueprint
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.offset
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.unit.IntRect
import com.android.compose.animation.scene.SceneScope
-import com.android.compose.modifiers.height
-import com.android.compose.modifiers.width
import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection
import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection
import com.android.systemui.keyguard.ui.composable.section.ClockSection
@@ -62,47 +57,104 @@
@Composable
override fun SceneScope.Content(modifier: Modifier) {
- val context = LocalContext.current
- val lockIconBounds = lockSection.lockIconBounds(context)
val isUdfpsVisible = viewModel.isUdfpsVisible
- Box(
+ Layout(
+ content = {
+ // Constrained to above the lock icon.
+ Column(
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) }
+ with(clockSection) { SmallClock(modifier = Modifier.fillMaxWidth()) }
+ with(smartSpaceSection) { SmartSpace(modifier = Modifier.fillMaxWidth()) }
+ with(clockSection) { LargeClock(modifier = Modifier.fillMaxWidth()) }
+ with(notificationSection) {
+ Notifications(modifier = Modifier.fillMaxWidth().weight(1f))
+ }
+ if (!isUdfpsVisible) {
+ with(ambientIndicationSection) {
+ AmbientIndication(modifier = Modifier.fillMaxWidth())
+ }
+ }
+ }
+
+ with(lockSection) { LockIcon() }
+
+ // Aligned to bottom and constrained to below the lock icon.
+ Column(modifier = Modifier.fillMaxWidth()) {
+ if (isUdfpsVisible) {
+ with(ambientIndicationSection) {
+ AmbientIndication(modifier = Modifier.fillMaxWidth())
+ }
+ }
+
+ with(bottomAreaSection) { IndicationArea(modifier = Modifier.fillMaxWidth()) }
+ }
+
+ // Aligned to bottom and NOT constrained by the lock icon.
+ with(bottomAreaSection) {
+ Shortcut(isStart = true, applyPadding = true)
+ Shortcut(isStart = false, applyPadding = true)
+ }
+ },
modifier = modifier,
- ) {
- Column(
- modifier = Modifier.fillMaxWidth().height { lockIconBounds.top },
- ) {
- with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) }
- with(clockSection) { SmallClock(modifier = Modifier.fillMaxWidth()) }
- with(smartSpaceSection) { SmartSpace(modifier = Modifier.fillMaxWidth()) }
- with(clockSection) { LargeClock(modifier = Modifier.fillMaxWidth()) }
- with(notificationSection) {
- Notifications(modifier = Modifier.fillMaxWidth().weight(1f))
- }
- if (!isUdfpsVisible) {
- with(ambientIndicationSection) {
- AmbientIndication(modifier = Modifier.fillMaxWidth())
- }
- }
- }
+ ) { measurables, constraints ->
+ check(measurables.size == 5)
+ val (
+ aboveLockIconMeasurable,
+ lockIconMeasurable,
+ belowLockIconMeasurable,
+ startShortcutMeasurable,
+ endShortcutMeasurable,
+ ) = measurables
- with(lockSection) {
- LockIcon(
- modifier =
- Modifier.width { lockIconBounds.width() }
- .height { lockIconBounds.height() }
- .offset { IntOffset(lockIconBounds.left, lockIconBounds.top) }
+ val noMinConstraints =
+ constraints.copy(
+ minWidth = 0,
+ minHeight = 0,
)
- }
+ val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints)
+ val lockIconBounds =
+ IntRect(
+ left = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Left],
+ top = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Top],
+ right = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Right],
+ bottom = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Bottom],
+ )
- Column(modifier = Modifier.fillMaxWidth().align(Alignment.BottomCenter)) {
- if (isUdfpsVisible) {
- with(ambientIndicationSection) {
- AmbientIndication(modifier = Modifier.fillMaxWidth())
- }
- }
+ val aboveLockIconPlaceable =
+ aboveLockIconMeasurable.measure(
+ noMinConstraints.copy(maxHeight = lockIconBounds.top)
+ )
+ val belowLockIconPlaceable =
+ belowLockIconMeasurable.measure(
+ noMinConstraints.copy(maxHeight = constraints.maxHeight - lockIconBounds.bottom)
+ )
+ val startShortcutPleaceable = startShortcutMeasurable.measure(noMinConstraints)
+ val endShortcutPleaceable = endShortcutMeasurable.measure(noMinConstraints)
- with(bottomAreaSection) { BottomArea(modifier = Modifier.fillMaxWidth()) }
+ layout(constraints.maxWidth, constraints.maxHeight) {
+ aboveLockIconPlaceable.place(
+ x = 0,
+ y = 0,
+ )
+ lockIconPlaceable.place(
+ x = lockIconBounds.left,
+ y = lockIconBounds.top,
+ )
+ belowLockIconPlaceable.place(
+ x = 0,
+ y = constraints.maxHeight - belowLockIconPlaceable.height,
+ )
+ startShortcutPleaceable.place(
+ x = 0,
+ y = constraints.maxHeight - startShortcutPleaceable.height,
+ )
+ endShortcutPleaceable.place(
+ x = constraints.maxWidth - endShortcutPleaceable.width,
+ y = constraints.maxHeight - endShortcutPleaceable.height,
+ )
}
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
index fa913f1..4c119c7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
@@ -16,24 +16,13 @@
package com.android.systemui.keyguard.ui.composable.blueprint
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.heightIn
-import androidx.compose.foundation.layout.offset
-import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.dimensionResource
-import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.unit.IntRect
import com.android.compose.animation.scene.SceneScope
-import com.android.compose.modifiers.height
-import com.android.compose.modifiers.width
import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection
import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection
import com.android.systemui.keyguard.ui.composable.section.ClockSection
@@ -42,12 +31,10 @@
import com.android.systemui.keyguard.ui.composable.section.SmartSpaceSection
import com.android.systemui.keyguard.ui.composable.section.StatusBarSection
import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel
-import com.android.systemui.res.R
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoSet
import javax.inject.Inject
-import kotlin.math.roundToInt
/**
* Renders the lockscreen scene when showing with the default layout (e.g. vertical phone form
@@ -70,96 +57,107 @@
@Composable
override fun SceneScope.Content(modifier: Modifier) {
- val context = LocalContext.current
- val lockIconBounds = lockSection.lockIconBounds(context)
val isUdfpsVisible = viewModel.isUdfpsVisible
- Box(
+ Layout(
+ content = {
+ // Constrained to above the lock icon.
+ Column(
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) }
+ with(clockSection) { SmallClock(modifier = Modifier.fillMaxWidth()) }
+ with(smartSpaceSection) { SmartSpace(modifier = Modifier.fillMaxWidth()) }
+ with(clockSection) { LargeClock(modifier = Modifier.fillMaxWidth()) }
+ with(notificationSection) {
+ Notifications(modifier = Modifier.fillMaxWidth().weight(1f))
+ }
+ if (!isUdfpsVisible) {
+ with(ambientIndicationSection) {
+ AmbientIndication(modifier = Modifier.fillMaxWidth())
+ }
+ }
+ }
+
+ // Constrained to the left of the lock icon (in left-to-right layouts).
+ with(bottomAreaSection) { Shortcut(isStart = true, applyPadding = false) }
+
+ with(lockSection) { LockIcon() }
+
+ // Constrained to the right of the lock icon (in left-to-right layouts).
+ with(bottomAreaSection) { Shortcut(isStart = false, applyPadding = false) }
+
+ // Aligned to bottom and constrained to below the lock icon.
+ Column(modifier = Modifier.fillMaxWidth()) {
+ if (isUdfpsVisible) {
+ with(ambientIndicationSection) {
+ AmbientIndication(modifier = Modifier.fillMaxWidth())
+ }
+ }
+
+ with(bottomAreaSection) { IndicationArea(modifier = Modifier.fillMaxWidth()) }
+ }
+ },
modifier = modifier,
- ) {
- Column(
- modifier = Modifier.fillMaxWidth().height { lockIconBounds.top },
- ) {
- with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) }
- with(clockSection) { SmallClock(modifier = Modifier.fillMaxWidth()) }
- with(smartSpaceSection) { SmartSpace(modifier = Modifier.fillMaxWidth()) }
- with(clockSection) { LargeClock(modifier = Modifier.fillMaxWidth()) }
- with(notificationSection) {
- Notifications(modifier = Modifier.fillMaxWidth().weight(1f))
- }
- if (!isUdfpsVisible) {
- with(ambientIndicationSection) {
- AmbientIndication(modifier = Modifier.fillMaxWidth())
- }
- }
- }
+ ) { measurables, constraints ->
+ check(measurables.size == 5)
+ val (
+ aboveLockIconMeasurable,
+ startSideShortcutMeasurable,
+ lockIconMeasurable,
+ endSideShortcutMeasurable,
+ belowLockIconMeasurable,
+ ) = measurables
- val shortcutSizePx =
- with(LocalDensity.current) { bottomAreaSection.shortcutSizeDp().toSize() }
+ val noMinConstraints =
+ constraints.copy(
+ minWidth = 0,
+ minHeight = 0,
+ )
- Row(
- verticalAlignment = Alignment.CenterVertically,
- modifier =
- Modifier.fillMaxWidth().offset {
- val rowTop =
- if (shortcutSizePx.height > lockIconBounds.height()) {
- (lockIconBounds.top -
- (shortcutSizePx.height + lockIconBounds.height()) / 2)
- .roundToInt()
- } else {
- lockIconBounds.top
- }
+ val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints)
+ val lockIconBounds =
+ IntRect(
+ left = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Left],
+ top = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Top],
+ right = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Right],
+ bottom = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Bottom],
+ )
- IntOffset(0, rowTop)
- },
- ) {
- Spacer(Modifier.weight(1f))
+ val aboveLockIconPlaceable =
+ aboveLockIconMeasurable.measure(
+ noMinConstraints.copy(maxHeight = lockIconBounds.top)
+ )
+ val startSideShortcutPlaceable = startSideShortcutMeasurable.measure(noMinConstraints)
+ val endSideShortcutPlaceable = endSideShortcutMeasurable.measure(noMinConstraints)
+ val belowLockIconPlaceable =
+ belowLockIconMeasurable.measure(
+ noMinConstraints.copy(maxHeight = constraints.maxHeight - lockIconBounds.bottom)
+ )
- with(bottomAreaSection) { Shortcut(isStart = true) }
-
- Spacer(Modifier.weight(1f))
-
- with(lockSection) {
- LockIcon(
- modifier =
- Modifier.width { lockIconBounds.width() }
- .height { lockIconBounds.height() }
- )
- }
-
- Spacer(Modifier.weight(1f))
-
- with(bottomAreaSection) { Shortcut(isStart = false) }
-
- Spacer(Modifier.weight(1f))
- }
-
- Column(modifier = Modifier.fillMaxWidth().align(Alignment.BottomCenter)) {
- if (isUdfpsVisible) {
- with(ambientIndicationSection) {
- AmbientIndication(modifier = Modifier.fillMaxWidth())
- }
- }
-
- with(bottomAreaSection) {
- IndicationArea(
- modifier =
- Modifier.fillMaxWidth()
- .padding(
- horizontal =
- dimensionResource(
- R.dimen.keyguard_affordance_horizontal_offset
- )
- )
- .padding(
- bottom =
- dimensionResource(
- R.dimen.keyguard_affordance_vertical_offset
- )
- )
- .heightIn(min = shortcutSizeDp().height),
- )
- }
+ layout(constraints.maxWidth, constraints.maxHeight) {
+ aboveLockIconPlaceable.place(
+ x = 0,
+ y = 0,
+ )
+ startSideShortcutPlaceable.placeRelative(
+ x = lockIconBounds.left / 2 - startSideShortcutPlaceable.width / 2,
+ y = lockIconBounds.center.y - startSideShortcutPlaceable.height / 2,
+ )
+ lockIconPlaceable.place(
+ x = lockIconBounds.left,
+ y = lockIconBounds.top,
+ )
+ endSideShortcutPlaceable.placeRelative(
+ x =
+ lockIconBounds.right + (constraints.maxWidth - lockIconBounds.right) / 2 -
+ endSideShortcutPlaceable.width / 2,
+ y = lockIconBounds.center.y - endSideShortcutPlaceable.height / 2,
+ )
+ belowLockIconPlaceable.place(
+ x = 0,
+ y = constraints.maxHeight - belowLockIconPlaceable.height,
+ )
}
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
index 53e4be3..db20f65 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
@@ -19,7 +19,6 @@
import android.view.View
import android.widget.ImageView
import androidx.annotation.IdRes
-import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -58,38 +57,17 @@
private val indicationAreaViewModel: KeyguardIndicationAreaViewModel,
private val keyguardRootViewModel: KeyguardRootViewModel,
) {
- @Composable
- fun SceneScope.BottomArea(
- modifier: Modifier = Modifier,
- ) {
- Row(
- modifier =
- modifier
- .padding(
- horizontal =
- dimensionResource(R.dimen.keyguard_affordance_horizontal_offset)
- )
- .padding(
- bottom = dimensionResource(R.dimen.keyguard_affordance_vertical_offset)
- ),
- ) {
- Shortcut(
- isStart = true,
- )
-
- IndicationArea(
- modifier = Modifier.weight(1f),
- )
-
- Shortcut(
- isStart = false,
- )
- }
- }
-
+ /**
+ * Renders a single lockscreen shortcut.
+ *
+ * @param isStart Whether the shortcut goes on the left (in left-to-right locales).
+ * @param applyPadding Whether to apply padding around the shortcut, this is needed if the
+ * shortcut is placed along the edges of the display.
+ */
@Composable
fun SceneScope.Shortcut(
isStart: Boolean,
+ applyPadding: Boolean,
modifier: Modifier = Modifier,
) {
MovableElement(
@@ -103,6 +81,12 @@
falsingManager = falsingManager,
vibratorHelper = vibratorHelper,
indicationController = indicationController,
+ modifier =
+ if (applyPadding) {
+ Modifier.shortcutPadding()
+ } else {
+ Modifier
+ }
)
}
}
@@ -113,7 +97,7 @@
) {
MovableElement(
key = IndicationAreaElementKey,
- modifier = modifier,
+ modifier = modifier.shortcutPadding(),
) {
IndicationArea(
indicationAreaViewModel = indicationAreaViewModel,
@@ -218,6 +202,14 @@
modifier = modifier.fillMaxWidth(),
)
}
+
+ @Composable
+ private fun Modifier.shortcutPadding(): Modifier {
+ return this.padding(
+ horizontal = dimensionResource(R.dimen.keyguard_affordance_horizontal_offset)
+ )
+ .padding(bottom = dimensionResource(R.dimen.keyguard_affordance_vertical_offset))
+ }
}
private val StartButtonElementKey = ElementKey("StartButton")
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt
index 8bbe424b..d93863d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt
@@ -17,8 +17,6 @@
package com.android.systemui.keyguard.ui.composable.section
import android.content.Context
-import android.graphics.Point
-import android.graphics.Rect
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.compose.foundation.background
@@ -28,11 +26,17 @@
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.layout
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntRect
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.biometrics.AuthController
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.ui.composable.blueprint.BlueprintAlignmentLines
import com.android.systemui.res.R
import javax.inject.Inject
@@ -49,8 +53,33 @@
key = LockIconElementKey,
modifier = modifier,
) {
+ val context = LocalContext.current
Box(
- modifier = Modifier.background(Color.Red),
+ modifier =
+ Modifier.background(Color.Red).layout { measurable, _ ->
+ val lockIconBounds = lockIconBounds(context)
+ val placeable =
+ measurable.measure(
+ Constraints.fixed(
+ width = lockIconBounds.width,
+ height = lockIconBounds.height,
+ )
+ )
+ layout(
+ width = placeable.width,
+ height = placeable.height,
+ alignmentLines =
+ mapOf(
+ BlueprintAlignmentLines.LockIcon.Left to lockIconBounds.left,
+ BlueprintAlignmentLines.LockIcon.Top to lockIconBounds.top,
+ BlueprintAlignmentLines.LockIcon.Right to lockIconBounds.right,
+ BlueprintAlignmentLines.LockIcon.Bottom to
+ lockIconBounds.bottom,
+ ),
+ ) {
+ placeable.place(0, 0)
+ }
+ },
) {
Text(
text = "TODO(b/316211368): Lock",
@@ -67,9 +96,9 @@
* On devices that support UDFPS (under-display fingerprint sensor), the bounds of the icon are
* the same as the bounds of the sensor.
*/
- fun lockIconBounds(
+ private fun lockIconBounds(
context: Context,
- ): Rect {
+ ): IntRect {
val windowViewBounds = windowManager.currentWindowMetrics.bounds
var widthPx = windowViewBounds.right.toFloat()
if (featureFlags.isEnabled(Flags.LOCKSCREEN_ENABLE_LANDSCAPE)) {
@@ -85,36 +114,33 @@
val lockIconRadiusPx = (defaultDensity * 36).toInt()
val udfpsLocation = authController.udfpsLocation
- return if (authController.isUdfpsSupported && udfpsLocation != null) {
- centerLockIcon(udfpsLocation, authController.udfpsRadius)
- } else {
- val scaleFactor = authController.scaleFactor
- val bottomPaddingPx =
- context.resources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom)
- val heightPx = windowViewBounds.bottom.toFloat()
+ val (center, radius) =
+ if (authController.isUdfpsSupported && udfpsLocation != null) {
+ Pair(
+ IntOffset(
+ x = udfpsLocation.x,
+ y = udfpsLocation.y,
+ ),
+ authController.udfpsRadius.toInt(),
+ )
+ } else {
+ val scaleFactor = authController.scaleFactor
+ val bottomPaddingPx =
+ context.resources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom)
+ val heightPx = windowViewBounds.bottom.toFloat()
- centerLockIcon(
- Point(
- (widthPx / 2).toInt(),
- (heightPx - ((bottomPaddingPx + lockIconRadiusPx) * scaleFactor)).toInt()
- ),
- lockIconRadiusPx * scaleFactor
- )
- }
- }
+ Pair(
+ IntOffset(
+ x = (widthPx / 2).toInt(),
+ y =
+ (heightPx - ((bottomPaddingPx + lockIconRadiusPx) * scaleFactor))
+ .toInt(),
+ ),
+ (lockIconRadiusPx * scaleFactor).toInt(),
+ )
+ }
- private fun centerLockIcon(
- center: Point,
- radius: Float,
- ): Rect {
- return Rect().apply {
- set(
- center.x - radius.toInt(),
- center.y - radius.toInt(),
- center.x + radius.toInt(),
- center.y + radius.toInt(),
- )
- }
+ return IntRect(center, radius)
}
}