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

Commit a58a7d6a authored by Nick Chameyev's avatar Nick Chameyev Committed by Android (Google) Code Review
Browse files

Merge "Add statusbar unfold animation" into sc-v2-dev

parents 62065602 edbea0fc
Loading
Loading
Loading
Loading
+56 −30
Original line number Diff line number Diff line
@@ -36,6 +36,13 @@ class UnfoldMoveFromCenterAnimator @JvmOverloads constructor(
     * [View.setTranslationY]
     */
    private val translationApplier: TranslationApplier = object : TranslationApplier {},
    /**
     * Allows to set custom implementation for getting
     * view location. Could be useful if logical view bounds
     * are different than actual bounds (e.g. view container may
     * have larger width than width of the items in the container)
     */
    private val viewCenterProvider: ViewCenterProvider = object : ViewCenterProvider {}
) : UnfoldTransitionProgressProvider.TransitionProgressListener {

    private val screenSize = Point()
@@ -43,6 +50,8 @@ class UnfoldMoveFromCenterAnimator @JvmOverloads constructor(

    private val animatedViews: MutableList<AnimatedView> = arrayListOf()

    private var lastAnimationProgress: Float = 0f

    /**
     * Updates display properties in order to calculate the initial position for the views
     * Must be called before [registerViewForAnimation]
@@ -57,6 +66,19 @@ class UnfoldMoveFromCenterAnimator @JvmOverloads constructor(
            windowManager.defaultDisplay.rotation == Surface.ROTATION_180
    }

    /**
     * If target view positions have changed (e.g. because of layout changes) call this method
     * to re-query view positions and update the translations
     */
    fun updateViewPositions() {
        animatedViews.forEach { animatedView ->
            animatedView.view.get()?.let {
                animatedView.updateAnimatedView(it)
            }
        }
        onTransitionProgress(lastAnimationProgress)
    }

    /**
     * Registers a view to be animated, the view should be measured and layouted
     * After finishing the animation it is necessary to clear
@@ -85,45 +107,30 @@ class UnfoldMoveFromCenterAnimator @JvmOverloads constructor(
                )
            }
        }
        lastAnimationProgress = progress
    }

    private fun createAnimatedView(view: View): AnimatedView {
        val viewCenter = getViewCenter(view)
    private fun createAnimatedView(view: View): AnimatedView =
        AnimatedView(view = WeakReference(view)).updateAnimatedView(view)

    private fun AnimatedView.updateAnimatedView(view: View): AnimatedView {
        val viewCenter = Point()
        viewCenterProvider.getViewCenter(view, viewCenter)

        val viewCenterX = viewCenter.x
        val viewCenterY = viewCenter.y

        val translationX: Float
        val translationY: Float

        if (isVerticalFold) {
            val distanceFromScreenCenterToViewCenter = screenSize.x / 2 - viewCenterX
            translationX = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
            translationY = 0f
            startTranslationX = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
            startTranslationY = 0f
        } else {
            val distanceFromScreenCenterToViewCenter = screenSize.y / 2 - viewCenterY
            translationX = 0f
            translationY = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
            startTranslationX = 0f
            startTranslationY = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
        }

        return AnimatedView(
            view = WeakReference(view),
            startTranslationX = translationX,
            startTranslationY = translationY
        )
    }

    private fun getViewCenter(view: View): Point {
        val viewLocation = IntArray(2)
        view.getLocationOnScreen(viewLocation)

        val viewX = viewLocation[0]
        val viewY = viewLocation[1]

        val outPoint = Point()
        outPoint.x = viewX + view.width / 2
        outPoint.y = viewY + view.height / 2

        return outPoint
        return this
    }

    /**
@@ -139,10 +146,29 @@ class UnfoldMoveFromCenterAnimator @JvmOverloads constructor(
        }
    }

    /**
     * Interface that allows to use custom logic to get the center of the view
     */
    interface ViewCenterProvider {
        /**
         * Called when we need to get the center of the view
         */
        fun getViewCenter(view: View, outPoint: Point) {
            val viewLocation = IntArray(2)
            view.getLocationOnScreen(viewLocation)

            val viewX = viewLocation[0]
            val viewY = viewLocation[1]

            outPoint.x = viewX + view.width / 2
            outPoint.y = viewY + view.height / 2
        }
    }

    private class AnimatedView(
        val view: WeakReference<View>,
        val startTranslationX: Float,
        val startTranslationY: Float
        var startTranslationX: Float = 0f,
        var startTranslationY: Float = 0f
    )
}

+0 −39
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.statusbar.phone;

import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.util.ViewController;

/** Controller for {@link PhoneStatusBarView}. */
public class PhoneStatusBarViewController extends ViewController<PhoneStatusBarView> {

    protected PhoneStatusBarViewController(
            PhoneStatusBarView view,
            CommandQueue commandQueue) {
        super(view);
        mView.setPanelEnabledProvider(commandQueue::panelsEnabled);
    }

    @Override
    protected void onViewAttached() {
    }

    @Override
    protected void onViewDetached() {
    }
}
+93 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.statusbar.phone

import android.graphics.Point
import android.view.View
import android.view.ViewGroup
import com.android.systemui.R
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.util.ViewController

/** Controller for [PhoneStatusBarView].  */
class PhoneStatusBarViewController(
    view: PhoneStatusBarView,
    commandQueue: CommandQueue,
    statusBarMoveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?
) : ViewController<PhoneStatusBarView>(view) {

    override fun onViewAttached() {}
    override fun onViewDetached() {}

    init {
        mView.setPanelEnabledProvider {
            commandQueue.panelsEnabled()
        }

        statusBarMoveFromCenterAnimationController?.let { animationController ->
            val statusBarLeftSide: View = mView.findViewById(R.id.status_bar_left_side)
            val systemIconArea: ViewGroup = mView.findViewById(R.id.system_icon_area)

            val viewCenterProvider = StatusBarViewsCenterProvider()
            val viewsToAnimate = arrayOf(
                statusBarLeftSide,
                systemIconArea
            )

            animationController.init(viewsToAnimate, viewCenterProvider)

            mView.addOnLayoutChangeListener { _, left, _, right, _, oldLeft, _, oldRight, _ ->
                val widthChanged = right - left != oldRight - oldLeft
                if (widthChanged) {
                    statusBarMoveFromCenterAnimationController.onStatusBarWidthChanged()
                }
            }
        }
    }

    private class StatusBarViewsCenterProvider : UnfoldMoveFromCenterAnimator.ViewCenterProvider {
        override fun getViewCenter(view: View, outPoint: Point) =
            when (view.id) {
                R.id.status_bar_left_side -> {
                    // items aligned to the start, return start center point
                    getViewEdgeCenter(view, outPoint, isStart = true)
                }
                R.id.system_icon_area -> {
                    // items aligned to the end, return end center point
                    getViewEdgeCenter(view, outPoint, isStart = false)
                }
                else -> super.getViewCenter(view, outPoint)
            }

        /**
         * Returns start or end (based on [isStart]) center point of the view
         */
        private fun getViewEdgeCenter(view: View, outPoint: Point, isStart: Boolean) {
            val isRtl = view.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
            val isLeftEdge = isRtl xor isStart

            val viewLocation = IntArray(2)
            view.getLocationOnScreen(viewLocation)

            val viewX = viewLocation[0]
            val viewY = viewLocation[1]

            outPoint.x = viewX + if (isLeftEdge) view.height / 2 else view.width - view.height / 2
            outPoint.y = viewY + view.height / 2
        }
    }
}
+9 −1
Original line number Diff line number Diff line
@@ -536,6 +536,7 @@ public class StatusBar extends SystemUI implements
    private final FeatureFlags mFeatureFlags;
    private final UnfoldTransitionConfig mUnfoldTransitionConfig;
    private final Lazy<UnfoldLightRevealOverlayAnimation> mUnfoldLightRevealOverlayAnimation;
    private final Lazy<StatusBarMoveFromCenterAnimationController> mMoveFromCenterAnimation;
    private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
    private final MessageRouter mMessageRouter;
    private final WallpaperManager mWallpaperManager;
@@ -768,6 +769,7 @@ public class StatusBar extends SystemUI implements
            BrightnessSlider.Factory brightnessSliderFactory,
            UnfoldTransitionConfig unfoldTransitionConfig,
            Lazy<UnfoldLightRevealOverlayAnimation> unfoldLightRevealOverlayAnimation,
            Lazy<StatusBarMoveFromCenterAnimationController> statusBarUnfoldAnimationController,
            OngoingCallController ongoingCallController,
            SystemStatusAnimationScheduler animationScheduler,
            StatusBarLocationPublisher locationPublisher,
@@ -860,6 +862,7 @@ public class StatusBar extends SystemUI implements
        mBrightnessSliderFactory = brightnessSliderFactory;
        mUnfoldTransitionConfig = unfoldTransitionConfig;
        mUnfoldLightRevealOverlayAnimation = unfoldLightRevealOverlayAnimation;
        mMoveFromCenterAnimation = statusBarUnfoldAnimationController;
        mOngoingCallController = ongoingCallController;
        mAnimationScheduler = animationScheduler;
        mStatusBarLocationPublisher = locationPublisher;
@@ -1141,8 +1144,13 @@ public class StatusBar extends SystemUI implements
                        sendInitialExpansionAmount(listener);
                    }

                    StatusBarMoveFromCenterAnimationController moveFromCenterAnimation = null;
                    if (mUnfoldTransitionConfig.isEnabled()) {
                        moveFromCenterAnimation = mMoveFromCenterAnimation.get();
                    }
                    mPhoneStatusBarViewController =
                            new PhoneStatusBarViewController(mStatusBarView, mCommandQueue);
                            new PhoneStatusBarViewController(mStatusBarView, mCommandQueue,
                                    moveFromCenterAnimation);
                    mPhoneStatusBarViewController.init();

                    mBatteryMeterViewController = new BatteryMeterViewController(
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.statusbar.phone

import android.view.View
import android.view.WindowManager
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator.ViewCenterProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import javax.inject.Inject

@SysUISingleton
class StatusBarMoveFromCenterAnimationController @Inject constructor(
    private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
    private val windowManager: WindowManager
) {

    private lateinit var moveFromCenterAnimator: UnfoldMoveFromCenterAnimator

    fun init(viewsToAnimate: Array<View>, viewCenterProvider: ViewCenterProvider) {
        moveFromCenterAnimator = UnfoldMoveFromCenterAnimator(windowManager,
            viewCenterProvider = viewCenterProvider)

        unfoldTransitionProgressProvider.addCallback(object : TransitionProgressListener {
            override fun onTransitionStarted() {
                moveFromCenterAnimator.updateDisplayProperties()

                viewsToAnimate.forEach {
                    moveFromCenterAnimator.registerViewForAnimation(it)
                }
            }

            override fun onTransitionFinished() {
                moveFromCenterAnimator.onTransitionFinished()
                moveFromCenterAnimator.clearRegisteredViews()
            }

            override fun onTransitionProgress(progress: Float) {
                moveFromCenterAnimator.onTransitionProgress(progress)
            }
        })
    }

    fun onStatusBarWidthChanged() {
        moveFromCenterAnimator.updateViewPositions()
    }
}
Loading