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

Commit 4af70810 authored by Matt Pietal's avatar Matt Pietal Committed by Automerger Merge Worker
Browse files

[DO NOT MERGE] Coordinated DREAMING->LOCKSCREEN animation am: 79c7aaa0

parents 042c3767 79c7aaa0
Loading
Loading
Loading
Loading
+0 −21
Original line number Diff line number Diff line
@@ -743,27 +743,6 @@
    <!-- How long in milliseconds before full burn-in protection is achieved. -->
    <integer name="config_dreamOverlayMillisUntilFullJitter">240000</integer>

    <!-- The duration in milliseconds of the y-translation animation when waking up from
         the dream -->
    <integer name="config_dreamOverlayOutTranslationYDurationMs">333</integer>
    <!-- The delay in milliseconds of the y-translation animation when waking up from
         the dream for the complications at the bottom of the screen -->
    <integer name="config_dreamOverlayOutTranslationYDelayBottomMs">33</integer>
    <!-- The delay in milliseconds of the y-translation animation when waking up from
         the dream for the complications at the top of the screen -->
    <integer name="config_dreamOverlayOutTranslationYDelayTopMs">117</integer>
    <!-- The duration in milliseconds of the alpha animation when waking up from the dream -->
    <integer name="config_dreamOverlayOutAlphaDurationMs">200</integer>
    <!-- The delay in milliseconds of the alpha animation when waking up from the dream for the
         complications at the top of the screen -->
    <integer name="config_dreamOverlayOutAlphaDelayTopMs">217</integer>
    <!-- The delay in milliseconds of the alpha animation when waking up from the dream for the
         complications at the bottom of the screen -->
    <integer name="config_dreamOverlayOutAlphaDelayBottomMs">133</integer>
    <!-- The duration in milliseconds of the blur animation when waking up from
         the dream -->
    <integer name="config_dreamOverlayOutBlurDurationMs">250</integer>

    <integer name="complicationFadeOutMs">500</integer>

    <integer name="complicationFadeInMs">500</integer>
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.dreams

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.policy.CallbackController
import javax.inject.Inject

/** Dream-related callback information */
@SysUISingleton
class DreamCallbackController @Inject constructor() :
    CallbackController<DreamCallbackController.DreamCallback> {

    private val callbacks = mutableSetOf<DreamCallbackController.DreamCallback>()

    override fun addCallback(callback: DreamCallbackController.DreamCallback) {
        callbacks.add(callback)
    }

    override fun removeCallback(callback: DreamCallbackController.DreamCallback) {
        callbacks.remove(callback)
    }

    fun onWakeUp() {
        callbacks.forEach { it.onWakeUp() }
    }

    interface DreamCallback {
        fun onWakeUp()
    }
}
+84 −80
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ import android.animation.ValueAnimator
import android.view.View
import android.view.animation.Interpolator
import androidx.core.animation.doOnEnd
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
import com.android.systemui.dreams.complication.ComplicationHostViewController
import com.android.systemui.dreams.complication.ComplicationLayoutParams
@@ -29,10 +32,20 @@ import com.android.systemui.dreams.complication.ComplicationLayoutParams.POSITIO
import com.android.systemui.dreams.complication.ComplicationLayoutParams.POSITION_TOP
import com.android.systemui.dreams.complication.ComplicationLayoutParams.Position
import com.android.systemui.dreams.dagger.DreamOverlayModule
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.Companion.DREAM_ANIMATION_DURATION
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.BlurUtils
import com.android.systemui.statusbar.CrossFadeHelper
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
import com.android.systemui.util.concurrency.DelayableExecutor
import javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.launch

/** Controller for dream overlay animations. */
class DreamOverlayAnimationsController
@@ -43,6 +56,8 @@ constructor(
    private val mStatusBarViewController: DreamOverlayStatusBarViewController,
    private val mOverlayStateController: DreamOverlayStateController,
    @Named(DreamOverlayModule.DREAM_BLUR_RADIUS) private val mDreamBlurRadius: Int,
    private val transitionViewModel: DreamingToLockscreenTransitionViewModel,
    private val configController: ConfigurationController,
    @Named(DreamOverlayModule.DREAM_IN_BLUR_ANIMATION_DURATION)
    private val mDreamInBlurAnimDurationMs: Long,
    @Named(DreamOverlayModule.DREAM_IN_COMPLICATIONS_ANIMATION_DURATION)
@@ -51,22 +66,10 @@ constructor(
    private val mDreamInTranslationYDistance: Int,
    @Named(DreamOverlayModule.DREAM_IN_TRANSLATION_Y_DURATION)
    private val mDreamInTranslationYDurationMs: Long,
    @Named(DreamOverlayModule.DREAM_OUT_TRANSLATION_Y_DISTANCE)
    private val mDreamOutTranslationYDistance: Int,
    @Named(DreamOverlayModule.DREAM_OUT_TRANSLATION_Y_DURATION)
    private val mDreamOutTranslationYDurationMs: Long,
    @Named(DreamOverlayModule.DREAM_OUT_TRANSLATION_Y_DELAY_BOTTOM)
    private val mDreamOutTranslationYDelayBottomMs: Long,
    @Named(DreamOverlayModule.DREAM_OUT_TRANSLATION_Y_DELAY_TOP)
    private val mDreamOutTranslationYDelayTopMs: Long,
    @Named(DreamOverlayModule.DREAM_OUT_ALPHA_DURATION) private val mDreamOutAlphaDurationMs: Long,
    @Named(DreamOverlayModule.DREAM_OUT_ALPHA_DELAY_BOTTOM)
    private val mDreamOutAlphaDelayBottomMs: Long,
    @Named(DreamOverlayModule.DREAM_OUT_ALPHA_DELAY_TOP) private val mDreamOutAlphaDelayTopMs: Long,
    @Named(DreamOverlayModule.DREAM_OUT_BLUR_DURATION) private val mDreamOutBlurDurationMs: Long
) {

    private var mAnimator: Animator? = null
    private lateinit var view: View

    /**
     * Store the current alphas at the various positions. This is so that we may resume an animation
@@ -76,9 +79,63 @@ constructor(

    private var mCurrentBlurRadius: Float = 0f

    fun init(view: View) {
        this.view = view

        view.repeatWhenAttached {
            val configurationBasedDimensions = MutableStateFlow(loadFromResources(view))
            val configCallback =
                object : ConfigurationListener {
                    override fun onDensityOrFontScaleChanged() {
                        configurationBasedDimensions.value = loadFromResources(view)
                    }
                }

            configController.addCallback(configCallback)

            repeatOnLifecycle(Lifecycle.State.CREATED) {
                /* Translation animations, when moving from DREAMING->LOCKSCREEN state */
                launch {
                    configurationBasedDimensions
                        .flatMapLatest {
                            transitionViewModel.dreamOverlayTranslationY(it.translationYPx)
                        }
                        .collect { px ->
                            setElementsTranslationYAtPosition(
                                px,
                                ComplicationLayoutParams.POSITION_TOP
                            )
                            setElementsTranslationYAtPosition(
                                px,
                                ComplicationLayoutParams.POSITION_BOTTOM
                            )
                        }
                }

                /* Alpha animations, when moving from DREAMING->LOCKSCREEN state */
                launch {
                    transitionViewModel.dreamOverlayAlpha.collect { alpha ->
                        setElementsAlphaAtPosition(
                            alpha = alpha,
                            position = ComplicationLayoutParams.POSITION_TOP,
                            fadingOut = true,
                        )
                        setElementsAlphaAtPosition(
                            alpha = alpha,
                            position = ComplicationLayoutParams.POSITION_BOTTOM,
                            fadingOut = true,
                        )
                    }
                }
            }

            configController.removeCallback(configCallback)
        }
    }

    /** Starts the dream content and dream overlay entry animations. */
    @JvmOverloads
    fun startEntryAnimations(view: View, animatorBuilder: () -> AnimatorSet = { AnimatorSet() }) {
    fun startEntryAnimations(animatorBuilder: () -> AnimatorSet = { AnimatorSet() }) {
        cancelAnimations()

        mAnimator =
@@ -113,73 +170,9 @@ constructor(
    }

    /** Starts the dream content and dream overlay exit animations. */
    @JvmOverloads
    fun startExitAnimations(
        view: View,
        doneCallback: () -> Unit,
        animatorBuilder: () -> AnimatorSet = { AnimatorSet() }
    ) {
    fun wakeUp(doneCallback: Runnable, executor: DelayableExecutor) {
        cancelAnimations()

        mAnimator =
            animatorBuilder().apply {
                playTogether(
                    blurAnimator(
                        view = view,
                        // Start the blurring wherever the entry animation ended, in
                        // case it was cancelled early.
                        fromBlurRadius = mCurrentBlurRadius,
                        toBlurRadius = mDreamBlurRadius.toFloat(),
                        durationMs = mDreamOutBlurDurationMs,
                        interpolator = Interpolators.EMPHASIZED_ACCELERATE
                    ),
                    translationYAnimator(
                        from = 0f,
                        to = mDreamOutTranslationYDistance.toFloat(),
                        durationMs = mDreamOutTranslationYDurationMs,
                        delayMs = mDreamOutTranslationYDelayBottomMs,
                        positions = POSITION_BOTTOM,
                        interpolator = Interpolators.EMPHASIZED_ACCELERATE
                    ),
                    translationYAnimator(
                        from = 0f,
                        to = mDreamOutTranslationYDistance.toFloat(),
                        durationMs = mDreamOutTranslationYDurationMs,
                        delayMs = mDreamOutTranslationYDelayTopMs,
                        positions = POSITION_TOP,
                        interpolator = Interpolators.EMPHASIZED_ACCELERATE
                    ),
                    alphaAnimator(
                        from =
                            mCurrentAlphaAtPosition.getOrDefault(
                                key = POSITION_BOTTOM,
                                defaultValue = 1f
                            ),
                        to = 0f,
                        durationMs = mDreamOutAlphaDurationMs,
                        delayMs = mDreamOutAlphaDelayBottomMs,
                        positions = POSITION_BOTTOM
                    ),
                    alphaAnimator(
                        from =
                            mCurrentAlphaAtPosition.getOrDefault(
                                key = POSITION_TOP,
                                defaultValue = 1f
                            ),
                        to = 0f,
                        durationMs = mDreamOutAlphaDurationMs,
                        delayMs = mDreamOutAlphaDelayTopMs,
                        positions = POSITION_TOP
                    )
                )
                doOnEnd {
                    mAnimator = null
                    mOverlayStateController.setExitAnimationsRunning(false)
                    doneCallback()
                }
                start()
            }
        mOverlayStateController.setExitAnimationsRunning(true)
        executor.executeDelayed(doneCallback, DREAM_ANIMATION_DURATION.inWholeMilliseconds)
    }

    /** Cancels the dream content and dream overlay animations, if they're currently running. */
@@ -288,4 +281,15 @@ constructor(
            mStatusBarViewController.setTranslationY(translationY)
        }
    }

    private fun loadFromResources(view: View): ConfigurationBasedDimensions {
        return ConfigurationBasedDimensions(
            translationYPx =
                view.resources.getDimensionPixelSize(R.dimen.dream_overlay_exit_y_offset),
        )
    }

    private data class ConfigurationBasedDimensions(
        val translationYPx: Int,
    )
}
+6 −7
Original line number Diff line number Diff line
@@ -42,9 +42,9 @@ import com.android.systemui.statusbar.BlurUtils;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.concurrency.DelayableExecutor;

import java.util.Arrays;
import java.util.concurrent.Executor;

import javax.inject.Inject;
import javax.inject.Named;
@@ -170,6 +170,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
    protected void onInit() {
        mStatusBarViewController.init();
        mComplicationHostViewController.init();
        mDreamOverlayAnimationsController.init(mView);
    }

    @Override
@@ -184,7 +185,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve

        // Start dream entry animations. Skip animations for low light clock.
        if (!mStateController.isLowLightActive()) {
            mDreamOverlayAnimationsController.startEntryAnimations(mView);
            mDreamOverlayAnimationsController.startEntryAnimations();
        }
    }

@@ -261,10 +262,8 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
     * @param onAnimationEnd Callback to trigger once animations are finished.
     * @param callbackExecutor Executor to execute the callback on.
     */
    public void wakeUp(@NonNull Runnable onAnimationEnd, @NonNull Executor callbackExecutor) {
        mDreamOverlayAnimationsController.startExitAnimations(mView, () -> {
            callbackExecutor.execute(onAnimationEnd);
            return null;
        });
    public void wakeUp(@NonNull Runnable onAnimationEnd,
            @NonNull DelayableExecutor callbackExecutor) {
        mDreamOverlayAnimationsController.wakeUp(onAnimationEnd, callbackExecutor);
    }
}
+8 −5
Original line number Diff line number Diff line
@@ -43,8 +43,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.complication.Complication;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;

import java.util.concurrent.Executor;
import com.android.systemui.util.concurrency.DelayableExecutor;

import javax.inject.Inject;
import javax.inject.Named;
@@ -61,10 +60,11 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
    // The Context is used to construct the hosting constraint layout and child overlay views.
    private final Context mContext;
    // The Executor ensures actions and ui updates happen on the same thread.
    private final Executor mExecutor;
    private final DelayableExecutor mExecutor;
    // A controller for the dream overlay container view (which contains both the status bar and the
    // content area).
    private DreamOverlayContainerViewController mDreamOverlayContainerViewController;
    private final DreamCallbackController mDreamCallbackController;
    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    @Nullable
    private final ComponentName mLowLightDreamComponent;
@@ -126,14 +126,15 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
    @Inject
    public DreamOverlayService(
            Context context,
            @Main Executor executor,
            @Main DelayableExecutor executor,
            WindowManager windowManager,
            DreamOverlayComponent.Factory dreamOverlayComponentFactory,
            DreamOverlayStateController stateController,
            KeyguardUpdateMonitor keyguardUpdateMonitor,
            UiEventLogger uiEventLogger,
            @Nullable @Named(LowLightDreamModule.LOW_LIGHT_DREAM_COMPONENT)
                    ComponentName lowLightDreamComponent) {
                    ComponentName lowLightDreamComponent,
            DreamCallbackController dreamCallbackController) {
        mContext = context;
        mExecutor = executor;
        mWindowManager = windowManager;
@@ -142,6 +143,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
        mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback);
        mStateController = stateController;
        mUiEventLogger = uiEventLogger;
        mDreamCallbackController = dreamCallbackController;

        final ViewModelStore viewModelStore = new ViewModelStore();
        final Complication.Host host =
@@ -217,6 +219,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
    public void onWakeUp(@NonNull Runnable onCompletedCallback) {
        mExecutor.execute(() -> {
            if (mDreamOverlayContainerViewController != null) {
                mDreamCallbackController.onWakeUp();
                mDreamOverlayContainerViewController.wakeUp(onCompletedCallback, mExecutor);
            }
        });
Loading