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

Commit 1672c546 authored by Mike Schneider's avatar Mike Schneider Committed by Android (Google) Code Review
Browse files

Merge changes from topic "shapes" into udc-qpr-dev

* changes:
  Add shapes to PIN bouncer
  Tweak AVDs to make them work with the compose androidx.compose.animation:animation-graphics library.
  Reformat AVDs to allow better understanding of the changes in the follow-up CL
parents fb2767b4 38928d30
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ android_library {
        "PlatformComposeCore",

        "androidx.compose.runtime_runtime",
        "androidx.compose.animation_animation-graphics",
        "androidx.compose.material3_material3",
        "androidx.activity_activity-compose",
    ],
+28 −23
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

@file:OptIn(ExperimentalAnimationApi::class)
@file:OptIn(ExperimentalAnimationApi::class, ExperimentalAnimationGraphicsApi::class)

package com.android.systemui.bouncer.ui.composable

@@ -29,11 +29,14 @@ import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.Canvas
import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi
import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.Image
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -61,8 +64,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.Constraints
@@ -70,6 +75,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.android.compose.animation.Easings
import com.android.compose.grid.VerticalGrid
import com.android.internal.R.id.image
import com.android.systemui.R
import com.android.systemui.bouncer.ui.viewmodel.ActionButtonAppearance
import com.android.systemui.bouncer.ui.viewmodel.EnteredKey
@@ -139,7 +145,8 @@ private fun PinInputDisplay(viewModel: PinBouncerViewModel) {
                        else -> EntryVisibility.Hidden
                    }

                ObscuredInputEntry(updateTransition(visibility, label = "Pin Entry $entry"))
                val shape = viewModel.pinShapes.getShape(entry.sequenceNumber)
                PinInputEntry(shape, updateTransition(visibility, label = "Pin Entry $entry"))

                LaunchedEffect(entry) {
                    // Remove entry from visiblePinEntries once the hide transition completed.
@@ -171,15 +178,11 @@ private sealed class EntryVisibility {
}

@Composable
private fun ObscuredInputEntry(transition: Transition<EntryVisibility>) {
private fun PinInputEntry(shapeResourceId: Int, transition: Transition<EntryVisibility>) {
    // spec: http://shortn/_DEhE3Xl2bi
    val shapePadding = 6.dp
    val shapeOvershootSize = 22.dp
    val dismissStaggerDelayMs = 33
    val dismissDurationMs = 450
    val expansionDurationMs = 250
    val shapeExpandDurationMs = 83
    val shapeRetractDurationMs = 167
    val shapeCollapseDurationMs = 200

    val animatedEntryWidth by
@@ -194,18 +197,16 @@ private fun ObscuredInputEntry(transition: Transition<EntryVisibility>) {
            },
            label = "entry space"
        ) { state ->
            if (state == EntryVisibility.Shown) entryShapeSize + (shapePadding * 2) else 0.dp
            if (state == EntryVisibility.Shown) entryShapeSize else 0.dp
        }

    val animatedShapeSize by
        transition.animateDp(
            transitionSpec = {
                when {
                    EntryVisibility.Hidden isTransitioningTo EntryVisibility.Shown ->
                        keyframes {
                            durationMillis = shapeExpandDurationMs + shapeRetractDurationMs
                            0.dp at 0 with Easings.Linear
                            shapeOvershootSize at shapeExpandDurationMs with Easings.Legacy
                    EntryVisibility.Hidden isTransitioningTo EntryVisibility.Shown -> {
                        // The AVD contains the entry transition.
                        snap()
                    }
                    targetState is EntryVisibility.BulkHidden -> {
                        val target = targetState as EntryVisibility.BulkHidden
@@ -220,17 +221,21 @@ private fun ObscuredInputEntry(transition: Transition<EntryVisibility>) {
            },
            label = "shape size"
        ) { state ->
            when (state) {
                EntryVisibility.Shown -> entryShapeSize
                else -> 0.dp
            }
            if (state == EntryVisibility.Shown) entryShapeSize else 0.dp
        }

    val dotColor = MaterialTheme.colorScheme.onSurfaceVariant
    Layout(
        content = {
            // TODO(b/282730134): add support for dot shapes.
            Canvas(Modifier) { drawCircle(dotColor) }
            val image = AnimatedImageVector.animatedVectorResource(shapeResourceId)
            var atEnd by remember { mutableStateOf(false) }
            Image(
                painter = rememberAnimatedVectorPainter(image, atEnd),
                contentDescription = null,
                contentScale = ContentScale.Crop,
                colorFilter = ColorFilter.tint(dotColor),
            )
            LaunchedEffect(Unit) { atEnd = true }
        }
    ) { measurables, _ ->
        val shapeSizePx = animatedShapeSize.roundToPx()
@@ -507,7 +512,7 @@ private suspend fun showFailureAnimation(
    }
}

private val entryShapeSize = 16.dp
private val entryShapeSize = 30.dp

private val pinButtonSize = 84.dp
private val pinButtonErrorShrinkFactor = 67.dp / pinButtonSize
+40 −1
Original line number Diff line number Diff line
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="30dp" android:width="30dp" android:viewportHeight="30" android:viewportWidth="30"><group android:name="_R_G"><group android:name="_R_G_L_0_G" android:translateX="28.237000000000002" android:translateY="23.112000000000002"><path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M-13.24 -12.11 C-11.03,-12.11 -9.24,-10.32 -9.24,-8.11 C-9.24,-5.9 -11.03,-4.11 -13.24,-4.11 C-15.44,-4.11 -17.24,-5.9 -17.24,-8.11 C-17.24,-10.32 -15.44,-12.11 -13.24,-12.11c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="500" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
 No newline at end of file
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <aapt:attr name="android:drawable">
        <vector
            android:height="30dp"
            android:width="30dp"
            android:viewportHeight="30"
            android:viewportWidth="30">
            <group android:name="_R_G">
                <group
                    android:name="_R_G_L_0_G"
                    android:translateX="28.237000000000002"
                    android:translateY="23.112000000000002">
                    <path
                        android:name="_R_G_L_0_G_D_0_P_0"
                        android:strokeColor="#ffffff"
                        android:strokeLineCap="round"
                        android:strokeLineJoin="round"
                        android:strokeWidth="2"
                        android:strokeAlpha="1"
                        android:pathData=" M-13.24 -12.11 C-11.03,-12.11 -9.24,-10.32 -9.24,-8.11 C-9.24,-5.9 -11.03,-4.11 -13.24,-4.11 C-15.44,-4.11 -17.24,-5.9 -17.24,-8.11 C-17.24,-10.32 -15.44,-12.11 -13.24,-12.11c " />
                </group>
            </group>
            <group android:name="time_group" />
        </vector>
    </aapt:attr>
    <target android:name="time_group">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:propertyName="translateX"
                    android:duration="500"
                    android:startOffset="0"
                    android:valueFrom="0"
                    android:valueTo="1"
                    android:valueType="floatType" />
            </set>
        </aapt:attr>
    </target>
</animated-vector>
 No newline at end of file
+130 −1
Original line number Diff line number Diff line
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="30dp" android:width="30dp" android:viewportHeight="30" android:viewportWidth="30"><group android:name="_R_G"><group android:name="_R_G_L_0_G" android:translateX="28.54" android:translateY="23.54"><path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-13.54 -16.54 C-9.12,-16.54 -5.54,-12.96 -5.54,-8.54 C-5.54,-4.12 -9.12,-0.54 -13.54,-0.54 C-17.96,-0.54 -21.54,-4.12 -21.54,-8.54 C-21.54,-12.96 -17.96,-16.54 -13.54,-16.54c "/><path android:name="_R_G_L_0_G_D_1_P_0" android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="0" android:strokeAlpha="1" android:pathData=" M-13.54 -16.54 C-9.12,-16.54 -5.54,-12.96 -5.54,-8.54 C-5.54,-4.12 -9.12,-0.54 -13.54,-0.54 C-17.96,-0.54 -21.54,-4.12 -21.54,-8.54 C-21.54,-12.96 -17.96,-16.54 -13.54,-16.54c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="150" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="fillAlpha" android:duration="200" android:startOffset="150" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="150" android:startOffset="0" android:valueFrom="M-13.54 -16.54 C-9.12,-16.54 -5.54,-12.96 -5.54,-8.54 C-5.54,-4.12 -9.12,-0.54 -13.54,-0.54 C-17.96,-0.54 -21.54,-4.12 -21.54,-8.54 C-21.54,-12.96 -17.96,-16.54 -13.54,-16.54c " android:valueTo="M-13.54 -11.54 C-11.88,-11.54 -10.54,-10.2 -10.54,-8.54 C-10.54,-6.88 -11.88,-5.54 -13.54,-5.54 C-15.2,-5.54 -16.54,-6.88 -16.54,-8.54 C-16.54,-10.2 -15.2,-11.54 -13.54,-11.54c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="200" android:startOffset="150" android:valueFrom="M-13.54 -11.54 C-11.88,-11.54 -10.54,-10.2 -10.54,-8.54 C-10.54,-6.88 -11.88,-5.54 -13.54,-5.54 C-15.2,-5.54 -16.54,-6.88 -16.54,-8.54 C-16.54,-10.2 -15.2,-11.54 -13.54,-11.54c " android:valueTo="M-13.54 -12.54 C-11.33,-12.54 -9.54,-10.75 -9.54,-8.54 C-9.54,-6.33 -11.33,-4.54 -13.54,-4.54 C-15.75,-4.54 -17.54,-6.33 -17.54,-8.54 C-17.54,-10.75 -15.75,-12.54 -13.54,-12.54c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_1_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="strokeWidth" android:duration="150" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="strokeWidth" android:duration="50" android:startOffset="150" android:valueFrom="0" android:valueTo="2" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_1_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="150" android:startOffset="0" android:valueFrom="M-13.54 -16.54 C-9.12,-16.54 -5.54,-12.96 -5.54,-8.54 C-5.54,-4.12 -9.12,-0.54 -13.54,-0.54 C-17.96,-0.54 -21.54,-4.12 -21.54,-8.54 C-21.54,-12.96 -17.96,-16.54 -13.54,-16.54c " android:valueTo="M-13.54 -11.54 C-11.88,-11.54 -10.54,-10.2 -10.54,-8.54 C-10.54,-6.88 -11.88,-5.54 -13.54,-5.54 C-15.2,-5.54 -16.54,-6.88 -16.54,-8.54 C-16.54,-10.2 -15.2,-11.54 -13.54,-11.54c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="200" android:startOffset="150" android:valueFrom="M-13.54 -11.54 C-11.88,-11.54 -10.54,-10.2 -10.54,-8.54 C-10.54,-6.88 -11.88,-5.54 -13.54,-5.54 C-15.2,-5.54 -16.54,-6.88 -16.54,-8.54 C-16.54,-10.2 -15.2,-11.54 -13.54,-11.54c " android:valueTo="M-13.54 -12.54 C-11.33,-12.54 -9.54,-10.75 -9.54,-8.54 C-9.54,-6.33 -11.33,-4.54 -13.54,-4.54 C-15.75,-4.54 -17.54,-6.33 -17.54,-8.54 C-17.54,-10.75 -15.75,-12.54 -13.54,-12.54c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="500" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
 No newline at end of file
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <target android:name="_R_G_L_1_G">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="150"
                    android:propertyName="scaleX"
                    android:startOffset="0"
                    android:valueFrom="1"
                    android:valueTo="0.43"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="150"
                    android:propertyName="scaleY"
                    android:startOffset="0"
                    android:valueFrom="1"
                    android:valueTo="0.43"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
            </set>
        </aapt:attr>
    </target>
    <target android:name="_R_G_L_1_G_D_0_P_0">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:propertyName="fillAlpha"
                    android:duration="200"
                    android:startOffset="150"
                    android:valueFrom="1"
                    android:valueTo="0"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
            </set>
        </aapt:attr>
    </target>
    <target android:name="_R_G_L_0_G">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="200"
                    android:propertyName="scaleX"
                    android:startOffset="150"
                    android:valueFrom="0.65"
                    android:valueTo="1"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
                <objectAnimator
                    android:duration="200"
                    android:propertyName="scaleY"
                    android:startOffset="150"
                    android:valueFrom="0.65"
                    android:valueTo="1"
                    android:valueType="floatType">
                    <aapt:attr name="android:interpolator">
                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
                    </aapt:attr>
                </objectAnimator>
            </set>
        </aapt:attr>
    </target>
    <target android:name="time_group">
        <aapt:attr name="android:animation">
            <set android:ordering="together">
                <objectAnimator
                    android:duration="500"
                    android:propertyName="translateX"
                    android:startOffset="0"
                    android:valueFrom="0"
                    android:valueTo="1"
                    android:valueType="floatType" />
            </set>
        </aapt:attr>
    </target>
    <aapt:attr name="android:drawable">
        <vector
            android:width="30dp"
            android:height="30dp"
            android:viewportHeight="30"
            android:viewportWidth="30">
            <group android:name="_R_G">
                <group
                    android:name="_R_G_L_1_G"
                    android:pivotX="-13.54"
                    android:pivotY="-8.54"
                    android:scaleX="1"
                    android:scaleY="1"
                    android:translateX="28.54"
                    android:translateY="23.54">
                    <path
                        android:name="_R_G_L_1_G_D_0_P_0"
                        android:fillAlpha="1"
                        android:fillColor="#ffffff"
                        android:fillType="nonZero"
                        android:pathData=" M-13.54 -16.54 C-9.12,-16.54 -5.54,-12.96 -5.54,-8.54 C-5.54,-4.12 -9.12,-0.54 -13.54,-0.54 C-17.96,-0.54 -21.54,-4.12 -21.54,-8.54 C-21.54,-12.96 -17.96,-16.54 -13.54,-16.54c " />
                </group>
                <group
                    android:name="_R_G_L_0_G"
                    android:pivotX="317.509"
                    android:pivotY="-826.986"
                    android:scaleX="0.65"
                    android:scaleY="0.65"
                    android:translateX="-302.509"
                    android:translateY="841.986">
                    <path
                        android:name="_R_G_L_0_G_D_0_P_0"
                        android:fillAlpha="1"
                        android:fillColor="#ffffff"
                        android:fillType="nonZero"
                        android:pathData=" M317.51 -821.99 C314.75,-821.99 312.51,-824.23 312.51,-826.99 C312.51,-829.74 314.75,-831.99 317.51,-831.99 C320.27,-831.99 322.51,-829.74 322.51,-826.99 C322.51,-824.23 320.27,-821.99 317.51,-821.99z  M317.51 -829.99 C315.86,-829.99 314.51,-828.64 314.51,-826.99 C314.51,-825.33 315.86,-823.99 317.51,-823.99 C319.16,-823.99 320.51,-825.33 320.51,-826.99 C320.51,-828.64 319.16,-829.99 317.51,-829.99z " />
                </group>
            </group>
            <group android:name="time_group" />
        </vector>
    </aapt:attr>
</animated-vector>
 No newline at end of file
+141 −1

File changed.

Preview size limit exceeded, changes collapsed.

Loading