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

Commit 24c93732 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 13482186 from 386c486c to 25Q3-release

Change-Id: Icf239789d927bae9400a4279d3f8b135a1534459
parents a515633b 386c486c
Loading
Loading
Loading
Loading
+13 −14
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.mechanics.effects

import com.android.mechanics.spec.BreakpointKey
import com.android.mechanics.spec.Mapping
import com.android.mechanics.spec.builder.Effect
import com.android.mechanics.spec.builder.EffectApplyScope
@@ -32,9 +33,18 @@ val MotionSpecBuilderScope.one: FixedValue
    get() = FixedValue.One

/** Produces a fixed [value]. */
open class FixedValue(val value: Float) : Effect {

    override fun EffectApplyScope.createSpec() {
class FixedValue(val value: Float) :
    Effect.PlaceableAfter, Effect.PlaceableBefore, Effect.PlaceableBetween {

    override fun MotionBuilderContext.intrinsicSize(): Float = Float.NaN

    override fun EffectApplyScope.createSpec(
        minLimit: Float,
        minLimitKey: BreakpointKey,
        maxLimit: Float,
        maxLimitKey: BreakpointKey,
        placement: EffectPlacement,
    ) {
        return unidirectional(Mapping.Fixed(value))
    }

@@ -43,14 +53,3 @@ open class FixedValue(val value: Float) : Effect {
        val One = FixedValue(1f)
    }
}

/** Produces a fixed [value], for a predefined [extent]. */
class FixedValueWithExtent(value: Float, private val extent: Float) : FixedValue(value) {
    init {
        require(extent > 0)
    }

    override fun MotionBuilderContext.measure(effectPlacement: EffectPlacement): Float {
        return extent * effectPlacement.directionSign
    }
}
+24 −23
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ class MagneticDetach(
    private val attachScale: Float = Defaults.AttachDetachScale * (attachPosition / detachPosition),
    private val detachSpring: SpringParameters = Defaults.Spring,
    private val attachSpring: SpringParameters = Defaults.Spring,
) : Effect {
) : Effect.PlaceableAfter, Effect.PlaceableBefore {

    init {
        require(attachPosition <= detachPosition)
@@ -65,16 +65,20 @@ class MagneticDetach(
        Detached,
    }

    override fun MotionBuilderContext.measure(effectPlacement: EffectPlacement): Float {
        return detachPosition.toPx() * effectPlacement.directionSign
    override fun MotionBuilderContext.intrinsicSize(): Float {
        return detachPosition.toPx()
    }

    override fun EffectApplyScope.createSpec() {
        val startPos = minLimit
        val reattachPos = startPos + attachPosition.toPx()
        val detachPos = maxLimit
        val startValue = baseValue(startPos)
        val detachValue = baseValue(detachPos)
    override fun EffectApplyScope.createSpec(
        minLimit: Float,
        minLimitKey: BreakpointKey,
        maxLimit: Float,
        maxLimitKey: BreakpointKey,
        placement: EffectPlacement,
    ) {
        val reattachPos = minLimit + attachPosition.toPx()
        val startValue = baseValue(minLimit)
        val detachValue = baseValue(maxLimit)
        val reattachValue = baseValue(reattachPos)

        val scaledDetachValue = startValue + (detachValue - startValue) * detachScale
@@ -83,15 +87,14 @@ class MagneticDetach(
        val attachKey = BreakpointKey("attach")

        forward(
            initialMapping = Mapping.Linear(startPos, startValue, detachPos, scaledDetachValue),
            initialMapping = Mapping.Linear(minLimit, startValue, maxLimit, scaledDetachValue),
            semantics = listOf(semanticState with State.Attached),
        ) {
            maxLimitSpring = detachSpring
            maxLimitSemantics = listOf(semanticState with State.Detached)
            after(spring = detachSpring, semantics = listOf(semanticState with State.Detached))
        }

        backward(
            initialMapping = Mapping.Linear(startPos, startValue, reattachPos, scaledReattachValue),
            initialMapping = Mapping.Linear(minLimit, startValue, reattachPos, scaledReattachValue),
            semantics = listOf(semanticState with State.Attached),
        ) {
            mapping(
@@ -125,10 +128,10 @@ class MagneticDetach(

                val tweakedMapping = Mapping { input ->
                    if (input <= pivotPos) {
                        val t = (input - startPos) / (pivotPos - startPos)
                        val t = (input - minLimit) / (pivotPos - minLimit)
                        lerp(startValue, pivotValue, t)
                    } else {
                        val t = (input - pivotPos) / (detachPos - pivotPos)
                        val t = (input - pivotPos) / (maxLimit - pivotPos)
                        lerp(pivotValue, scaledDetachValue, t)
                    }
                }
@@ -139,7 +142,6 @@ class MagneticDetach(
        }
    }

    companion object {
    object Defaults {
        val AttachDetachState = SemanticKey<State>()
        val AttachDetachScale = .3f
@@ -148,4 +150,3 @@ class MagneticDetach(
        val Spring = SpringParameters(stiffness = 800f, dampingRatio = 0.95f)
    }
}
}
+69 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.mechanics.effects

import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.android.mechanics.spec.BreakpointKey
import com.android.mechanics.spec.Mapping
import com.android.mechanics.spec.SemanticKey
import com.android.mechanics.spec.builder.Effect
import com.android.mechanics.spec.builder.EffectApplyScope
import com.android.mechanics.spec.builder.EffectPlacement
import com.android.mechanics.spec.builder.MotionBuilderContext
import com.android.mechanics.spec.with

/** Gesture effect to soft-limit. */
class Overdrag(
    private val overdragLimit: SemanticKey<Float?> = Defaults.OverdragLimit,
    private val maxOverdrag: Dp = Defaults.MaxOverdrag,
    private val tilt: Float = Defaults.tilt,
) : Effect.PlaceableBefore, Effect.PlaceableAfter {

    override fun MotionBuilderContext.intrinsicSize() = Float.POSITIVE_INFINITY

    override fun EffectApplyScope.createSpec(
        minLimit: Float,
        minLimitKey: BreakpointKey,
        maxLimit: Float,
        maxLimitKey: BreakpointKey,
        placement: EffectPlacement,
    ) {

        val maxOverdragPx = maxOverdrag.toPx()

        val limitValue = baseValue(placement.start)
        val mapping = Mapping { input ->
            val baseMapped = baseMapping.map(input)

            maxOverdragPx * kotlin.math.tanh((baseMapped - limitValue) / (maxOverdragPx * tilt)) +
                limitValue
        }

        unidirectional(mapping, listOf(overdragLimit with limitValue)) {
            if (!placement.isForward) {
                after(semantics = listOf(overdragLimit with null))
            }
        }
    }

    object Defaults {
        val OverdragLimit = SemanticKey<Float?>()
        val MaxOverdrag = 30.dp
        val tilt = 3f
    }
}
+12 −12
Original line number Diff line number Diff line
@@ -481,13 +481,6 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
                                guaranteeState.updatedSpringParameters(lastBreakpoint)
                        }

                        springState =
                            springState.calculateUpdatedState(
                                nextBreakpointCrossTime - lastAnimationTime,
                                springParameters,
                            )
                        lastAnimationTime = nextBreakpointCrossTime

                        val mappingBefore = mappings[segmentIndex]
                        val beforeBreakpoint = mappingBefore.map(nextBreakpoint.position)
                        val mappingAfter = mappings[segmentIndex + directionOffset]
@@ -505,7 +498,18 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
                                    "  after: $afterBreakpoint (mapping: $mappingAfter)",
                            )
                        }
                        hasJumped = hasJumped || delta != 0f

                        if (!hasJumped && delta != 0f) {
                            hasJumped = true
                            springState = springState.nudge(velocityDelta = directMappedVelocity)
                        }

                        springState =
                            springState.calculateUpdatedState(
                                nextBreakpointCrossTime - lastAnimationTime,
                                springParameters,
                            )
                        lastAnimationTime = nextBreakpointCrossTime

                        if (deltaIsFinite) {
                            springState = springState.nudge(displacementDelta = -delta)
@@ -530,10 +534,6 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
                            }
                    }

                    if (hasJumped) {
                        springState = springState.nudge(velocityDelta = directMappedVelocity)
                    }

                    val tightened = guarantee.updatedSpringParameters(segment.entryBreakpoint)

                    DiscontinuityAnimation(springState, tightened, lastAnimationTime)
+0 −13
Original line number Diff line number Diff line
@@ -136,19 +136,6 @@ fun interface Mapping {
        }
    }

    data class Tanh(val scaling: Float, val tilt: Float, val offset: Float = 0f) : Mapping {

        init {
            require(scaling.isFinite())
            require(tilt.isFinite())
            require(offset.isFinite())
        }

        override fun map(input: Float): Float {
            return scaling * kotlin.math.tanh((input + offset) / (scaling * tilt))
        }
    }

    companion object {
        val Zero = Fixed(0f)
        val One = Fixed(1f)
Loading