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

Commit c004f91d authored by Evan Laird's avatar Evan Laird Committed by Automerger Merge Worker
Browse files

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

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

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17143814

Change-Id: If8806d2077cdfb2f128eb15c2f762a2b75cecc53
parents 7914943a c13f7b91
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
@@ -37,7 +37,5 @@
            android:layout_gravity="center"
            android:layout_gravity="center"
            android:minWidth="@dimen/ongoing_appops_chip_min_width"
            android:minWidth="@dimen/ongoing_appops_chip_min_width"
            android:maxWidth="@dimen/ongoing_appops_chip_max_width"
            android:maxWidth="@dimen/ongoing_appops_chip_max_width"
            android:clipChildren="false"
            android:clipToPadding="false"
            />
            />
</com.android.systemui.privacy.OngoingPrivacyChip>
</com.android.systemui.privacy.OngoingPrivacyChip>
 No newline at end of file
+3 −0
Original line number Original line Diff line number Diff line
@@ -941,6 +941,9 @@
    <!--  Three privacy items. This value must not be exceeded  -->
    <!--  Three privacy items. This value must not be exceeded  -->
    <dimen name="ongoing_appops_chip_max_width">76dp</dimen>
    <dimen name="ongoing_appops_chip_max_width">76dp</dimen>
    <dimen name="ongoing_appops_dot_diameter">6dp</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  -->
    <!--  Total minimum padding to enforce to ensure that the dot can always show  -->
    <dimen name="ongoing_appops_dot_min_padding">20dp</dimen>
    <dimen name="ongoing_appops_dot_min_padding">20dp</dimen>


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


package com.android.systemui.statusbar.events
package com.android.systemui.statusbar.events


import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.content.Context
import android.graphics.Point
import android.graphics.Rect
import android.view.Gravity
import android.view.Gravity
import android.view.LayoutInflater
import android.view.LayoutInflater
import android.view.View
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.phone.StatusBarContentInsetsProvider
import com.android.systemui.statusbar.window.StatusBarWindowController
import com.android.systemui.statusbar.window.StatusBarWindowController
import javax.inject.Inject
import javax.inject.Inject
import kotlin.math.roundToInt


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


    private lateinit var animationWindowView: FrameLayout
    private lateinit var animationWindowView: FrameLayout


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


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


    override fun onChipAnimationStart(
    /**
        viewCreator: ViewCreator,
     * Give the chip controller a chance to inflate and configure the chip view before we start
        @SystemAnimationState state: Int
     * animating
    ) {
     */
        if (!initialized) init()
    fun prepareChipAnimation(viewCreator: ViewCreator) {

        if (!initialized) {
        if (state == ANIMATING_IN) {
            init()
        }
        animationDirection = if (animationWindowView.isLayoutRtl) RIGHT else LEFT
        animationDirection = if (animationWindowView.isLayoutRtl) RIGHT else LEFT


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


            currentAnimatedView?.apply {
    override fun onSystemEventAnimationBegin(): Animator {
                updateAnimatedViewBoundsForAmount(0.1f, this)
        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 {
        } else {
            // We are animating away
            createMoveOutAnimationDefault()
            currentAnimatedView!!.view.apply {
        }
                alpha = 1f

        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) {
        val width2 = ValueAnimator.ofInt(chipMinWidth, dotSize).apply {
        if (state == ANIMATING_IN) {
            startDelay = 150
            // Finished animating in
            duration = 333
            currentAnimatedView?.apply {
            interpolator = STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_2
                updateAnimatedViewBoundsForAmount(1f, this)
            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 {
                } else {
            // Finished animating away
                    -(animatedValue as Int)
            currentAnimatedView!!.view.apply {
                }
                visibility = View.INVISIBLE
                updateAnimatedBoundsX(amt)
            }
            }
            animationWindowView.removeView(currentAnimatedView!!.view)
        }
        }

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


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


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


    private fun layoutParamsDefault(marginEnd: Int): FrameLayout.LayoutParams =
    private fun layoutParamsDefault(marginEnd: Int): FrameLayout.LayoutParams =
@@ -153,29 +235,55 @@ class SystemEventChipAnimationController @Inject constructor(
                it.marginEnd = marginEnd
                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) {
        when (animationDirection) {
            LEFT -> {
            LEFT -> {
                chip.setBoundsForAnimation(
                animRect.set((chipRight - width), animRect.top, chipRight, animRect.bottom)
                        (chipRight - (chipWidth * amt)).toInt(),
            } else /* RIGHT */ -> {
                        chip.view.top,
                animRect.set(chipLeft, animRect.top, (chipLeft + width), animRect.bottom)
                        chipRight,
                        chip.view.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
     * To be called during an animation. Sets the chip rect to animRect
    private fun left() = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation().left
     */
    private fun Float.amt() = 0.01f.coerceAtLeast(this)
    private fun updateCurrentAnimatedView() {
        currentAnimatedView?.setBoundsForAnimation(
                animRect.left, animRect.top, animRect.right, animRect.bottom
        )
    }
}
}


/**
/**
+123 −138
Original line number Original line Diff line number Diff line
@@ -19,14 +19,12 @@ package com.android.systemui.statusbar.events
import android.animation.Animator
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.annotation.IntDef
import android.annotation.IntDef
import android.os.Process
import android.os.Process
import android.provider.DeviceConfig
import android.provider.DeviceConfig
import android.util.Log
import android.util.Log
import android.view.animation.PathInterpolator
import com.android.systemui.Dumpable
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.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
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 com.android.systemui.util.time.SystemClock
import java.io.FileDescriptor
import java.io.FileDescriptor
import java.io.PrintWriter
import java.io.PrintWriter
import java.lang.IllegalStateException


import javax.inject.Inject
import javax.inject.Inject


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


        // Schedule the animation to start after a debounce period
        chipAnimationController.prepareChipAnimation(scheduledEvent!!.viewCreator)
        cancelExecutionRunnable = executor.executeDelayed({
        animationState = ANIMATION_QUEUED
            cancelExecutionRunnable = null
        executor.executeDelayed({
            animationState = ANIMATING_IN
            runChipAnimation()
            statusBarWindowController.setForceStatusBarVisible(true)
        }, DEBOUNCE_DELAY)

    }
            val entranceAnimator = ValueAnimator.ofFloat(1f, 0f)
            entranceAnimator.duration = ENTRANCE_ANIM_LENGTH
            entranceAnimator.addListener(systemAnimatorAdapter)
            entranceAnimator.addUpdateListener(systemUpdateListener)
            entranceAnimator.interpolator = STANDARD_ACCELERATE


            val chipAnimator = ValueAnimator.ofFloat(0f, 1f)
    /**
            chipAnimator.duration = CHIP_ANIM_LENGTH
     * 1. Define a total budget for the chip animation (1500ms)
            chipAnimator.addListener(
     * 2. Send out callbacks to listeners so that they can generate animations locally
                    ChipAnimatorAdapter(RUNNING_CHIP_ANIM, scheduledEvent!!.viewCreator))
     * 3. Update the scheduler state so that clients know where we are
            chipAnimator.addUpdateListener(chipUpdateListener)
     * 4. Maybe: provide scaffolding such as: dot location, margins, etc
            chipAnimator.interpolator = STANDARD_DECELERATE
     * 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()
        val animSet = collectStartAnimations()
            aSet2.playSequentially(entranceAnimator, chipAnimator)
        if (animSet.totalDuration > 500) {
            aSet2.start()
            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({
        executor.executeDelayed({
            val animSet2 = collectFinishAnimations()
            animationState = ANIMATING_OUT
            animationState = ANIMATING_OUT

            animSet2.addListener(object : AnimatorListenerAdapter() {
                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() {
                override fun onAnimationEnd(animation: Animator?) {
                override fun onAnimationEnd(animation: Animator?) {
                    animationState = if (hasPersistentDot) {
                        SHOWING_PERSISTENT_DOT
                    } else {
                        IDLE
                    }

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


                val chipAnimator = ValueAnimator.ofFloat(1f, 0f)
    private fun collectStartAnimations(): AnimatorSet {
                chipAnimator.duration = CHIP_ANIM_LENGTH
        val animators = mutableListOf<Animator>()
                val endState = if (hasPersistentDot) {
        listeners.forEach { listener ->
                    SHOWING_PERSISTENT_DOT
            listener.onSystemEventAnimationBegin()?.let { anim ->
                } else {
                animators.add(anim)
                    IDLE
            }
        }
        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) {
        if (hasPersistentDot) {
            val dotAnim = notifyTransitionToPersistentDot()
            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()
        return animSet

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


    private fun notifyTransitionToPersistentDot(): Animator? {
    private fun notifyTransitionToPersistentDot(): Animator? {
@@ -257,18 +281,6 @@ class SystemStatusAnimationScheduler @Inject constructor(
        return null
        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) {
    override fun addCallback(listener: SystemStatusAnimationCallback) {
        Assert.isMainThread()
        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>) {
    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
        pw.println("Scheduled event: $scheduledEvent")
        pw.println("Scheduled event: $scheduledEvent")
        pw.println("Has persistent privacy dot: $hasPersistentDot")
        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
 * create space for the chip animation to display. This means hiding the system elements in the
 * status bar and keyguard.
 * 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
 * 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
 * interpolation they choose but realistically these are most likely to be simple alpha transitions
 */
 */
interface SystemStatusAnimationCallback {
interface SystemStatusAnimationCallback {
    @JvmDefault fun onSystemChromeAnimationUpdate(animator: ValueAnimator) {}
    /** Implement this method to return an [Animator] or [AnimatorSet] that presents the chip */
    @JvmDefault fun onSystemChromeAnimationStart() {}
    fun onSystemEventAnimationBegin(): Animator? { return null }
    @JvmDefault fun onSystemChromeAnimationEnd() {}
    /** 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
    // Best method name, change my mind
    @JvmDefault
    @JvmDefault
@@ -363,50 +337,61 @@ interface SystemStatusAnimationCallback {
    @JvmDefault fun onHidePersistentDot(): Animator? { return null }
    @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)
@Retention(AnnotationRetention.SOURCE)
@IntDef(
@IntDef(
        value = [
        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
annotation class SystemAnimationState


/** No animation is in progress */
/** No animation is in progress */
const val IDLE = 0
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 */
/** 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 */
/** 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 */
/** 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 */
/** 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 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
 * The total time spent on the chip animation is 1500ms, broken up into 3 sections:
 * we give to the system to animate system elements out of the way. Total chip animation length
 *   - 500ms to animate the chip in (including animating system icons away)
 * will be equivalent to 2*chip_anim_length + display_length
 *   - 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 DISPLAY_LENGTH = 1000L
private const val CHIP_ANIM_LENGTH = 250L
// 1s + entrance time + chip anim_length
private const val DISPLAY_LENGTH = 1500L


private const val MIN_UPTIME: Long = 5 * 1000
private const val MIN_UPTIME: Long = 5 * 1000


+1 −23

File changed.

Preview size limit exceeded, changes collapsed.

Loading