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

Commit c13f7b91 authored by Evan Laird's avatar Evan Laird Committed by Android (Google) Code Review
Browse files

Merge changes from topics "presubmit-am-7250e98934bc40cbaa91f4d3fe499617",...

Merge changes from topics "presubmit-am-7250e98934bc40cbaa91f4d3fe499617", "presubmit-am-a05bb8af1eb24cd390463ad38288dc31" into tm-dev

* changes:
  Rework system event animations to a federated model
  Don't transition to ongoing privacy dot if still animating
parents 521df749 c1b85a8b
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -37,7 +37,5 @@
            android:layout_gravity="center"
            android:minWidth="@dimen/ongoing_appops_chip_min_width"
            android:maxWidth="@dimen/ongoing_appops_chip_max_width"
            android:clipChildren="false"
            android:clipToPadding="false"
            />
</com.android.systemui.privacy.OngoingPrivacyChip>
 No newline at end of file
+3 −0
Original line number Diff line number Diff line
@@ -941,6 +941,9 @@
    <!--  Three privacy items. This value must not be exceeded  -->
    <dimen name="ongoing_appops_chip_max_width">76dp</dimen>
    <dimen name="ongoing_appops_dot_diameter">6dp</dimen>
    <dimen name="ongoing_appops_chip_min_animation_width">10dp</dimen>
    <dimen name="ongoing_appops_chip_animation_in_status_bar_translation_x">15dp</dimen>
    <dimen name="ongoing_appops_chip_animation_out_status_bar_translation_x">7dp</dimen>
    <!--  Total minimum padding to enforce to ensure that the dot can always show  -->
    <dimen name="ongoing_appops_dot_min_padding">20dp</dimen>

+192 −84
Original line number Diff line number Diff line
@@ -16,9 +16,12 @@

package com.android.systemui.statusbar.events

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Point
import android.graphics.Rect
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
@@ -30,6 +33,7 @@ import com.android.systemui.R
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
import com.android.systemui.statusbar.window.StatusBarWindowController
import javax.inject.Inject
import kotlin.math.roundToInt

/**
 * Controls the view for system event animations.
@@ -38,7 +42,7 @@ class SystemEventChipAnimationController @Inject constructor(
    private val context: Context,
    private val statusBarWindowController: StatusBarWindowController,
    private val contentInsetsProvider: StatusBarContentInsetsProvider
) : SystemStatusChipAnimationCallback {
) : SystemStatusAnimationCallback {

    private lateinit var animationWindowView: FrameLayout

@@ -49,22 +53,24 @@ class SystemEventChipAnimationController @Inject constructor(
    private var chipRight = 0
    private var chipLeft = 0
    private var chipWidth = 0
    private var dotCenter = Point(0, 0)
    private var chipMinWidth = context.resources.getDimensionPixelSize(
            R.dimen.ongoing_appops_chip_min_animation_width)
    private var dotSize = context.resources.getDimensionPixelSize(
            R.dimen.ongoing_appops_dot_diameter)
    // If the chip animates away to a persistent dot, then we modify the CHIP_OUT animation
    private var isAnimatingToDot = false
    // Use during animation so that multiple animators can update the drawing rect
    private var animRect = Rect()

    // TODO: move to dagger
    private var initialized = false

    override fun onChipAnimationStart(
        viewCreator: ViewCreator,
        @SystemAnimationState state: Int
    ) {
        if (!initialized) init()

        if (state == ANIMATING_IN) {
    /**
     * Give the chip controller a chance to inflate and configure the chip view before we start
     * animating
     */
    fun prepareChipAnimation(viewCreator: ViewCreator) {
        if (!initialized) {
            init()
        }
        animationDirection = if (animationWindowView.isLayoutRtl) RIGHT else LEFT

        // Initialize the animated view
@@ -97,43 +103,120 @@ class SystemEventChipAnimationController @Inject constructor(
                chipRight = contentRect.left + chipWidth
            }
        }
    }

            currentAnimatedView?.apply {
                updateAnimatedViewBoundsForAmount(0.1f, this)
    override fun onSystemEventAnimationBegin(): Animator {
        initializeAnimRect()

        val alphaIn = ValueAnimator.ofFloat(0f, 1f).apply {
            startDelay = 117
            duration = 83
            interpolator = null
            addUpdateListener { currentAnimatedView?.view?.alpha = animatedValue as Float }
        }
        val moveIn = ValueAnimator.ofInt(chipMinWidth, chipWidth).apply {
            startDelay = 117
            duration = 383
            interpolator = STATUS_BAR_X_MOVE_IN
            addUpdateListener {
                updateAnimatedViewBoundsWidth(animatedValue as Int)
            }
        }
        val animSet = AnimatorSet()
        animSet.playTogether(alphaIn, moveIn)
        return animSet
    }

    override fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator {
        initializeAnimRect()
        val finish = if (hasPersistentDot) {
            createMoveOutAnimationForDot()
        } else {
            // We are animating away
            currentAnimatedView!!.view.apply {
                alpha = 1f
            createMoveOutAnimationDefault()
        }

        finish.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator?) {
                animationWindowView.removeView(currentAnimatedView!!.view)
            }
        })

        return finish
    }

    private fun createMoveOutAnimationForDot(): Animator {
        val width1 = ValueAnimator.ofInt(chipWidth, chipMinWidth).apply {
            duration = 150
            interpolator = STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_1
            addUpdateListener {
                updateAnimatedViewBoundsWidth(it.animatedValue as Int)
            }
        }

    override fun onChipAnimationEnd(@SystemAnimationState state: Int) {
        if (state == ANIMATING_IN) {
            // Finished animating in
            currentAnimatedView?.apply {
                updateAnimatedViewBoundsForAmount(1f, this)
        val width2 = ValueAnimator.ofInt(chipMinWidth, dotSize).apply {
            startDelay = 150
            duration = 333
            interpolator = STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_2
            addUpdateListener {
                updateAnimatedViewBoundsWidth(it.animatedValue as Int)
            }
        }

        val keyFrame1Height = dotSize * 2
        val v = currentAnimatedView!!.view
        val chipVerticalCenter = v.top + v.measuredHeight / 2
        val height1 = ValueAnimator.ofInt(
                currentAnimatedView!!.view.measuredHeight, keyFrame1Height).apply {
            startDelay = 133
            duration = 100
            interpolator = STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_1
            addUpdateListener {
                updateAnimatedViewBoundsHeight(it.animatedValue as Int, chipVerticalCenter)
            }
        }

        val height2 = ValueAnimator.ofInt(keyFrame1Height, dotSize).apply {
            startDelay = 233
            duration = 250
            interpolator = STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_2
            addUpdateListener {
                updateAnimatedViewBoundsHeight(it.animatedValue as Int, chipVerticalCenter)
            }
        }

        // Move the chip view to overlap exactly with the privacy dot. The chip displays by default
        // exactly adjacent to the dot, so we can just move over by the diameter of the dot itself
        val moveOut = ValueAnimator.ofInt(0, dotSize).apply {
            startDelay = 50
            duration = 183
            interpolator = STATUS_CHIP_MOVE_TO_DOT
            addUpdateListener {
                // If RTL, we can just invert the move
                val amt = if (animationDirection == LEFT) {
                        animatedValue as Int
                } else {
            // Finished animating away
            currentAnimatedView!!.view.apply {
                visibility = View.INVISIBLE
                    -(animatedValue as Int)
                }
                updateAnimatedBoundsX(amt)
            }
            animationWindowView.removeView(currentAnimatedView!!.view)
        }

        val animSet = AnimatorSet()
        animSet.playTogether(width1, width2, height1, height2, moveOut)
        return animSet
    }

    override fun onChipAnimationUpdate(
        animator: ValueAnimator,
        @SystemAnimationState state: Int
    ) {
    private fun createMoveOutAnimationDefault(): Animator {
        val moveOut = ValueAnimator.ofInt(chipWidth, chipMinWidth).apply {
            duration = 383
            addUpdateListener {
                currentAnimatedView?.apply {
            val amt = (animator.animatedValue as Float).amt()
            view.alpha = (animator.animatedValue as Float)
            updateAnimatedViewBoundsForAmount(amt, this)
                    updateAnimatedViewBoundsWidth(it.animatedValue as Int)
                }
            }
        }
        return moveOut
    }

    private fun init() {
        initialized = true
@@ -144,7 +227,6 @@ class SystemEventChipAnimationController @Inject constructor(
        statusBarWindowController.addViewToWindow(animationWindowView, lp)
        animationWindowView.clipToPadding = false
        animationWindowView.clipChildren = false
        animationWindowView.measureAllChildren = true
    }

    private fun layoutParamsDefault(marginEnd: Int): FrameLayout.LayoutParams =
@@ -153,29 +235,55 @@ class SystemEventChipAnimationController @Inject constructor(
                it.marginEnd = marginEnd
            }

    private fun updateAnimatedViewBoundsForAmount(amt: Float, chip: BackgroundAnimatableView) {
    private fun initializeAnimRect() = animRect.set(
            chipLeft,
            currentAnimatedView!!.view.top,
            chipRight,
            currentAnimatedView!!.view.bottom)

    /**
     * To be called during an animation, sets the width and updates the current animated chip view
     */
    private fun updateAnimatedViewBoundsWidth(width: Int) {
        when (animationDirection) {
            LEFT -> {
                chip.setBoundsForAnimation(
                        (chipRight - (chipWidth * amt)).toInt(),
                        chip.view.top,
                        chipRight,
                        chip.view.bottom)
                animRect.set((chipRight - width), animRect.top, chipRight, animRect.bottom)
            } else /* RIGHT */ -> {
                animRect.set(chipLeft, animRect.top, (chipLeft + width), animRect.bottom)
            }
            else /* RIGHT */ -> {
                chip.setBoundsForAnimation(
                        chipLeft,
                        chip.view.top,
                        (chipLeft + (chipWidth * amt)).toInt(),
                        chip.view.bottom)
        }

        updateCurrentAnimatedView()
    }

    /**
     * To be called during an animation, updates the animation rect and sends the update to the chip
     */
    private fun updateAnimatedViewBoundsHeight(height: Int, verticalCenter: Int) {
        animRect.set(
                animRect.left,
                verticalCenter - (height.toFloat() / 2).roundToInt(),
                animRect.right,
                verticalCenter + (height.toFloat() / 2).roundToInt())

        updateCurrentAnimatedView()
    }

    /**
     * To be called during an animation, updates the animation rect offset and updates the chip
     */
    private fun updateAnimatedBoundsX(translation: Int) {
        currentAnimatedView?.view?.translationX = translation.toFloat()
    }

    private fun start() = if (animationWindowView.isLayoutRtl) right() else left()
    private fun right() = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation().right
    private fun left() = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation().left
    private fun Float.amt() = 0.01f.coerceAtLeast(this)
    /**
     * To be called during an animation. Sets the chip rect to animRect
     */
    private fun updateCurrentAnimatedView() {
        currentAnimatedView?.setBoundsForAnimation(
                animRect.left, animRect.top, animRect.right, animRect.bottom
        )
    }
}

/**
+123 −138
Original line number Diff line number Diff line
@@ -19,14 +19,12 @@ package com.android.systemui.statusbar.events
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.annotation.IntDef
import android.os.Process
import android.provider.DeviceConfig
import android.util.Log
import android.view.animation.PathInterpolator
import com.android.systemui.Dumpable
import com.android.systemui.animation.Interpolators.STANDARD_ACCELERATE
import com.android.systemui.animation.Interpolators.STANDARD_DECELERATE

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
@@ -38,6 +36,7 @@ import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.time.SystemClock
import java.io.FileDescriptor
import java.io.PrintWriter
import java.lang.IllegalStateException

import javax.inject.Inject

@@ -116,8 +115,11 @@ class SystemStatusAnimationScheduler @Inject constructor(
            scheduledEvent?.updateFromEvent(event)
            if (event.forceVisible) {
                hasPersistentDot = true
                // If we missed the chance to show the persistent dot, do it now
                if (animationState == IDLE) {
                    notifyTransitionToPersistentDot()
                }
            }
        } else {
            if (DEBUG) {
                Log.d(TAG, "ignoring event $event")
@@ -162,68 +164,90 @@ class SystemStatusAnimationScheduler @Inject constructor(
            return
        }

        // Schedule the animation to start after a debounce period
        cancelExecutionRunnable = executor.executeDelayed({
            cancelExecutionRunnable = null
            animationState = ANIMATING_IN
            statusBarWindowController.setForceStatusBarVisible(true)

            val entranceAnimator = ValueAnimator.ofFloat(1f, 0f)
            entranceAnimator.duration = ENTRANCE_ANIM_LENGTH
            entranceAnimator.addListener(systemAnimatorAdapter)
            entranceAnimator.addUpdateListener(systemUpdateListener)
            entranceAnimator.interpolator = STANDARD_ACCELERATE
        chipAnimationController.prepareChipAnimation(scheduledEvent!!.viewCreator)
        animationState = ANIMATION_QUEUED
        executor.executeDelayed({
            runChipAnimation()
        }, DEBOUNCE_DELAY)
    }

            val chipAnimator = ValueAnimator.ofFloat(0f, 1f)
            chipAnimator.duration = CHIP_ANIM_LENGTH
            chipAnimator.addListener(
                    ChipAnimatorAdapter(RUNNING_CHIP_ANIM, scheduledEvent!!.viewCreator))
            chipAnimator.addUpdateListener(chipUpdateListener)
            chipAnimator.interpolator = STANDARD_DECELERATE
    /**
     * 1. Define a total budget for the chip animation (1500ms)
     * 2. Send out callbacks to listeners so that they can generate animations locally
     * 3. Update the scheduler state so that clients know where we are
     * 4. Maybe: provide scaffolding such as: dot location, margins, etc
     * 5. Maybe: define a maximum animation length and enforce it. Probably only doable if we
     * collect all of the animators and run them together.
     */
    private fun runChipAnimation() {
        statusBarWindowController.setForceStatusBarVisible(true)
        animationState = ANIMATING_IN

            val aSet2 = AnimatorSet()
            aSet2.playSequentially(entranceAnimator, chipAnimator)
            aSet2.start()
        val animSet = collectStartAnimations()
        if (animSet.totalDuration > 500) {
            throw IllegalStateException("System animation total length exceeds budget. " +
                    "Expected: 500, actual: ${animSet.totalDuration}")
        }
        animSet.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator?) {
                animationState = RUNNING_CHIP_ANIM
            }
        })
        animSet.start()

        executor.executeDelayed({
            val animSet2 = collectFinishAnimations()
            animationState = ANIMATING_OUT

                val systemAnimator = ValueAnimator.ofFloat(0f, 1f)
                systemAnimator.duration = ENTRANCE_ANIM_LENGTH
                systemAnimator.addListener(systemAnimatorAdapter)
                systemAnimator.addUpdateListener(systemUpdateListener)
                systemAnimator.interpolator = STANDARD_DECELERATE
                systemAnimator.addListener(object : AnimatorListenerAdapter() {
            animSet2.addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator?) {
                    animationState = if (hasPersistentDot) {
                        SHOWING_PERSISTENT_DOT
                    } else {
                        IDLE
                    }

                    statusBarWindowController.setForceStatusBarVisible(false)
                }
            })
            animSet2.start()
            scheduledEvent = null
        }, DISPLAY_LENGTH)
    }

                val chipAnimator = ValueAnimator.ofFloat(1f, 0f)
                chipAnimator.duration = CHIP_ANIM_LENGTH
                val endState = if (hasPersistentDot) {
                    SHOWING_PERSISTENT_DOT
                } else {
                    IDLE
    private fun collectStartAnimations(): AnimatorSet {
        val animators = mutableListOf<Animator>()
        listeners.forEach { listener ->
            listener.onSystemEventAnimationBegin()?.let { anim ->
                animators.add(anim)
            }
        }
        animators.add(chipAnimationController.onSystemEventAnimationBegin())
        val animSet = AnimatorSet().also {
            it.playTogether(animators)
        }
                chipAnimator.addListener(
                    ChipAnimatorAdapter(endState, scheduledEvent!!.viewCreator))
                chipAnimator.addUpdateListener(chipUpdateListener)
                chipAnimator.interpolator = STANDARD_ACCELERATE

                val aSet2 = AnimatorSet()
        return animSet
    }

                aSet2.play(chipAnimator).before(systemAnimator)
    private fun collectFinishAnimations(): AnimatorSet {
        val animators = mutableListOf<Animator>()
        listeners.forEach { listener ->
            listener.onSystemEventAnimationFinish(hasPersistentDot)?.let { anim ->
                animators.add(anim)
            }
        }
        animators.add(chipAnimationController.onSystemEventAnimationFinish(hasPersistentDot))
        if (hasPersistentDot) {
            val dotAnim = notifyTransitionToPersistentDot()
                    if (dotAnim != null) aSet2.playTogether(systemAnimator, dotAnim)
            if (dotAnim != null) {
                animators.add(dotAnim)
            }
        }
        val animSet = AnimatorSet().also {
            it.playTogether(animators)
        }

                aSet2.start()

                scheduledEvent = null
            }, DISPLAY_LENGTH)
        }, DELAY)
        return animSet
    }

    private fun notifyTransitionToPersistentDot(): Animator? {
@@ -257,18 +281,6 @@ class SystemStatusAnimationScheduler @Inject constructor(
        return null
    }

    private fun notifySystemStart() {
        listeners.forEach { it.onSystemChromeAnimationStart() }
    }

    private fun notifySystemFinish() {
        listeners.forEach { it.onSystemChromeAnimationEnd() }
    }

    private fun notifySystemAnimationUpdate(anim: ValueAnimator) {
        listeners.forEach { it.onSystemChromeAnimationUpdate(anim) }
    }

    override fun addCallback(listener: SystemStatusAnimationCallback) {
        Assert.isMainThread()

@@ -287,24 +299,6 @@ class SystemStatusAnimationScheduler @Inject constructor(
        }
    }

    private val systemUpdateListener = ValueAnimator.AnimatorUpdateListener {
        anim -> notifySystemAnimationUpdate(anim)
    }

    private val systemAnimatorAdapter = object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(p0: Animator?) {
            notifySystemFinish()
        }

        override fun onAnimationStart(p0: Animator?) {
            notifySystemStart()
        }
    }

    private val chipUpdateListener = ValueAnimator.AnimatorUpdateListener {
        anim -> chipAnimationController.onChipAnimationUpdate(anim, animationState)
    }

    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
        pw.println("Scheduled event: $scheduledEvent")
        pw.println("Has persistent privacy dot: $hasPersistentDot")
@@ -318,24 +312,6 @@ class SystemStatusAnimationScheduler @Inject constructor(
            }
        }
    }

    inner class ChipAnimatorAdapter(
        @SystemAnimationState val endState: Int,
        val viewCreator: ViewCreator
    ) : AnimatorListenerAdapter() {
        override fun onAnimationEnd(p0: Animator?) {
            chipAnimationController.onChipAnimationEnd(animationState)
            animationState = if (endState == SHOWING_PERSISTENT_DOT && !hasPersistentDot) {
                IDLE
            } else {
                endState
            }
        }

        override fun onAnimationStart(p0: Animator?) {
            chipAnimationController.onChipAnimationStart(viewCreator, animationState)
        }
    }
}

/**
@@ -344,16 +320,14 @@ class SystemStatusAnimationScheduler @Inject constructor(
 * create space for the chip animation to display. This means hiding the system elements in the
 * status bar and keyguard.
 *
 * TODO: the chip animation really only has one client, we can probably remove it from this
 * interface
 *
 * The value animators themselves are simple animators from 0.0 to 1.0. Listeners can apply any
 * interpolation they choose but realistically these are most likely to be simple alpha transitions
 */
interface SystemStatusAnimationCallback {
    @JvmDefault fun onSystemChromeAnimationUpdate(animator: ValueAnimator) {}
    @JvmDefault fun onSystemChromeAnimationStart() {}
    @JvmDefault fun onSystemChromeAnimationEnd() {}
    /** Implement this method to return an [Animator] or [AnimatorSet] that presents the chip */
    fun onSystemEventAnimationBegin(): Animator? { return null }
    /** Implement this method to return an [Animator] or [AnimatorSet] that hides the chip */
    fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator? { return null }

    // Best method name, change my mind
    @JvmDefault
@@ -363,50 +337,61 @@ interface SystemStatusAnimationCallback {
    @JvmDefault fun onHidePersistentDot(): Animator? { return null }
}

interface SystemStatusChipAnimationCallback {
    fun onChipAnimationUpdate(animator: ValueAnimator, @SystemAnimationState state: Int) {}

    fun onChipAnimationStart(
        viewCreator: ViewCreator,
        @SystemAnimationState state: Int
    ) {}

    fun onChipAnimationEnd(@SystemAnimationState state: Int) {}
}

/**
 * Animation state IntDef
 */
@Retention(AnnotationRetention.SOURCE)
@IntDef(
        value = [
            IDLE, ANIMATING_IN, RUNNING_CHIP_ANIM, ANIMATING_OUT, SHOWING_PERSISTENT_DOT
            IDLE,
            ANIMATION_QUEUED,
            ANIMATING_IN,
            RUNNING_CHIP_ANIM,
            ANIMATING_OUT,
            SHOWING_PERSISTENT_DOT
        ]
)
annotation class SystemAnimationState

/** No animation is in progress */
const val IDLE = 0
/** An animation is queued, and awaiting the debounce period */
const val ANIMATION_QUEUED = 1
/** System is animating out, and chip is animating in */
const val ANIMATING_IN = 1
const val ANIMATING_IN = 2
/** Chip has animated in and is awaiting exit animation, and optionally playing its own animation */
const val RUNNING_CHIP_ANIM = 2
const val RUNNING_CHIP_ANIM = 3
/** Chip is animating away and system is animating back */
const val ANIMATING_OUT = 3
const val ANIMATING_OUT = 4
/** Chip has animated away, and the persistent dot is showing */
const val SHOWING_PERSISTENT_DOT = 4
const val SHOWING_PERSISTENT_DOT = 5

/** Commonly-needed interpolators can go here */
@JvmField val STATUS_BAR_X_MOVE_OUT = PathInterpolator(0.33f, 0f, 0f, 1f)
@JvmField val STATUS_BAR_X_MOVE_IN = PathInterpolator(0f, 0f, 0f, 1f)
/**
 * Status chip animation to dot have multiple stages of motion, the _1 and _2 interpolators should
 * be used in succession
 */
val STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_1 = PathInterpolator(0.44f, 0f, 0.25f, 1f)
val STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_2 = PathInterpolator(0.3f, 0f, 0.26f, 1f)
val STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_1 = PathInterpolator(0.4f, 0f, 0.17f, 1f)
val STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_2 = PathInterpolator(0.3f, 0f, 0f, 1f)
val STATUS_CHIP_MOVE_TO_DOT = PathInterpolator(0f, 0f, 0.05f, 1f)

private const val TAG = "SystemStatusAnimationScheduler"
private const val DELAY = 0L
private const val DEBOUNCE_DELAY = 100L

/**
 * The total time spent animation should be 1500ms. The entrance animation is how much time
 * we give to the system to animate system elements out of the way. Total chip animation length
 * will be equivalent to 2*chip_anim_length + display_length
 * The total time spent on the chip animation is 1500ms, broken up into 3 sections:
 *   - 500ms to animate the chip in (including animating system icons away)
 *   - 500ms holding the chip on screen
 *   - 500ms to animate the chip away (and system icons back)
 *
 *   So DISPLAY_LENGTH should be the sum of the first 2 phases, while the final 500ms accounts for
 *   the actual animation
 */
private const val ENTRANCE_ANIM_LENGTH = 250L
private const val CHIP_ANIM_LENGTH = 250L
// 1s + entrance time + chip anim_length
private const val DISPLAY_LENGTH = 1500L
private const val DISPLAY_LENGTH = 1000L

private const val MIN_UPTIME: Long = 5 * 1000

+1 −23

File changed.

Preview size limit exceeded, changes collapsed.

Loading