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

Commit 0843fc9b authored by Nick Chameyev's avatar Nick Chameyev Committed by Automerger Merge Worker
Browse files

Merge "Do not animate statusbar unfold when in portrait orientation" into...

Merge "Do not animate statusbar unfold when in portrait orientation" into sc-v2-dev am: 8264da57 am: 5dfd76ff

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

Change-Id: I26d66e2be09773ef45684cda47f95e69894308d7
parents 8fc75712 5dfd76ff
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
package com.android.systemui.unfold.util

import android.content.Context
import android.os.RemoteException
import android.util.Log
import android.view.IRotationWatcher
import android.view.IWindowManager
import android.view.Surface
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener

/**
 * [UnfoldTransitionProgressProvider] that emits transition progress only when the display has
 * default rotation or 180 degrees opposite rotation (ROTATION_0 or ROTATION_180).
 * It could be helpful to run the animation only when the display's rotation is perpendicular
 * to the fold.
 */
class NaturalRotationUnfoldProgressProvider(
    private val context: Context,
    private val windowManagerInterface: IWindowManager,
    unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider
) : UnfoldTransitionProgressProvider {

    private val scopedUnfoldTransitionProgressProvider =
            ScopedUnfoldTransitionProgressProvider(unfoldTransitionProgressProvider)
    private val rotationWatcher = RotationWatcher()

    private var isNaturalRotation: Boolean = false

    fun init() {
        try {
            windowManagerInterface.watchRotation(rotationWatcher, context.display.displayId)
        } catch (e: RemoteException) {
            throw e.rethrowFromSystemServer()
        }

        onRotationChanged(context.display.rotation)
    }

    private fun onRotationChanged(rotation: Int) {
        val isNewRotationNatural = rotation == Surface.ROTATION_0 ||
                rotation == Surface.ROTATION_180

        if (isNaturalRotation != isNewRotationNatural) {
            isNaturalRotation = isNewRotationNatural
            scopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(isNewRotationNatural)
        }
    }

    override fun destroy() {
        try {
            windowManagerInterface.removeRotationWatcher(rotationWatcher)
        } catch (e: RemoteException) {
            e.rethrowFromSystemServer()
        }

        scopedUnfoldTransitionProgressProvider.destroy()
    }

    override fun addCallback(listener: TransitionProgressListener) {
        scopedUnfoldTransitionProgressProvider.addCallback(listener)
    }

    override fun removeCallback(listener: TransitionProgressListener) {
        scopedUnfoldTransitionProgressProvider.removeCallback(listener)
    }

    private inner class RotationWatcher : IRotationWatcher.Stub() {
        override fun onRotationChanged(rotation: Int) {
            this@NaturalRotationUnfoldProgressProvider.onRotationChanged(rotation)
        }
    }
}
+142 −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.unfold.util;

import android.annotation.NonNull;
import android.annotation.Nullable;

import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;

import java.util.ArrayList;
import java.util.List;

/**
 * Manages progress listeners that can have smaller lifespan than the unfold animation.
 * Allows to limit getting transition updates to only when
 * {@link ScopedUnfoldTransitionProgressProvider#setReadyToHandleTransition} is called
 * with readyToHandleTransition = true
 *
 * If the transition has already started by the moment when the clients are ready to play
 * the transition then it will report transition started callback and current animation progress.
 */
public final class ScopedUnfoldTransitionProgressProvider implements
        UnfoldTransitionProgressProvider, TransitionProgressListener {

    private static final float PROGRESS_UNSET = -1f;

    @Nullable
    private UnfoldTransitionProgressProvider mSource;

    private final List<TransitionProgressListener> mListeners = new ArrayList<>();

    private boolean mIsReadyToHandleTransition;
    private boolean mIsTransitionRunning;
    private float mLastTransitionProgress = PROGRESS_UNSET;

    public ScopedUnfoldTransitionProgressProvider() {
        this(null);
    }

    public ScopedUnfoldTransitionProgressProvider(
            @Nullable UnfoldTransitionProgressProvider source) {
        setSourceProvider(source);
    }

    /**
     * Sets the source for the unfold transition progress updates,
     * it replaces current provider if it is already set
     * @param provider transition provider that emits transition progress updates
     */
    public void setSourceProvider(@Nullable UnfoldTransitionProgressProvider provider) {
        if (mSource != null) {
            mSource.removeCallback(this);
        }

        if (provider != null) {
            mSource = provider;
            mSource.addCallback(this);
        } else {
            mSource = null;
        }
    }

    /**
     * Allows to notify this provide whether the listeners can play the transition or not.
     * Call this method with readyToHandleTransition = true when all listeners
     * are ready to consume the transition progress events.
     * Call it with readyToHandleTransition = false when listeners can't process the events.
     */
    public void setReadyToHandleTransition(boolean isReadyToHandleTransition) {
        if (mIsTransitionRunning) {
            if (isReadyToHandleTransition) {
                mListeners.forEach(TransitionProgressListener::onTransitionStarted);

                if (mLastTransitionProgress != PROGRESS_UNSET) {
                    mListeners.forEach(listener ->
                            listener.onTransitionProgress(mLastTransitionProgress));
                }
            } else {
                mIsTransitionRunning = false;
                mListeners.forEach(TransitionProgressListener::onTransitionFinished);
            }
        }

        mIsReadyToHandleTransition = isReadyToHandleTransition;
    }

    @Override
    public void addCallback(@NonNull TransitionProgressListener listener) {
        mListeners.add(listener);
    }

    @Override
    public void removeCallback(@NonNull TransitionProgressListener listener) {
        mListeners.remove(listener);
    }

    @Override
    public void destroy() {
        mSource.removeCallback(this);
    }

    @Override
    public void onTransitionStarted() {
        this.mIsTransitionRunning = true;
        if (mIsReadyToHandleTransition) {
            mListeners.forEach(TransitionProgressListener::onTransitionStarted);
        }
    }

    @Override
    public void onTransitionProgress(float progress) {
        if (mIsReadyToHandleTransition) {
            mListeners.forEach(listener -> listener.onTransitionProgress(progress));
        }

        mLastTransitionProgress = progress;
    }

    @Override
    public void onTransitionFinished() {
        if (mIsReadyToHandleTransition) {
            mListeners.forEach(TransitionProgressListener::onTransitionFinished);
        }

        mIsTransitionRunning = false;
        mLastTransitionProgress = PROGRESS_UNSET;
    }
}
+51 −11
Original line number Diff line number Diff line
@@ -18,25 +18,28 @@ package com.android.systemui.statusbar.phone
import android.graphics.Point
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import com.android.systemui.R
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.unfold.UNFOLD_STATUS_BAR
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import com.android.systemui.util.ViewController
import javax.inject.Inject
import javax.inject.Named
import dagger.Lazy

/** Controller for [PhoneStatusBarView].  */
class PhoneStatusBarViewController(
class PhoneStatusBarViewController private constructor(
    view: PhoneStatusBarView,
    statusBarMoveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
    @Named(UNFOLD_STATUS_BAR) private val progressProvider: ScopedUnfoldTransitionProgressProvider?,
    private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
    touchEventHandler: PhoneStatusBarView.TouchEventHandler,
) : ViewController<PhoneStatusBarView>(view) {

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

    init {
        mView.setTouchEventHandler(touchEventHandler)

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

@@ -46,15 +49,33 @@ class PhoneStatusBarViewController(
                systemIconArea
            )

            animationController.init(viewsToAnimate, viewCenterProvider)
            mView.viewTreeObserver.addOnPreDrawListener(object :
                ViewTreeObserver.OnPreDrawListener {
                override fun onPreDraw(): Boolean {
                    animationController.onViewsReady(viewsToAnimate, viewCenterProvider)
                    mView.viewTreeObserver.removeOnPreDrawListener(this)
                    return true
                }
            })

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

        progressProvider?.setReadyToHandleTransition(true)
    }

    override fun onViewDetached() {
        progressProvider?.setReadyToHandleTransition(false)
        moveFromCenterAnimationController?.onViewDetached()
    }

    init {
        mView.setTouchEventHandler(touchEventHandler)
    }

    fun setImportantForAccessibility(mode: Int) {
@@ -92,4 +113,23 @@ class PhoneStatusBarViewController(
            outPoint.y = viewY + view.height / 2
        }
    }

    class Factory @Inject constructor(
        @Named(UNFOLD_STATUS_BAR)
        private val progressProvider: Lazy<ScopedUnfoldTransitionProgressProvider>,
        private val moveFromCenterController: Lazy<StatusBarMoveFromCenterAnimationController>,
        private val unfoldConfig: UnfoldTransitionConfig,
    ) {
        fun create(
            view: PhoneStatusBarView,
            touchEventHandler: PhoneStatusBarView.TouchEventHandler
        ): PhoneStatusBarViewController {
            return PhoneStatusBarViewController(
                view,
                if (unfoldConfig.isEnabled) progressProvider.get() else null,
                if (unfoldConfig.isEnabled) moveFromCenterController.get() else null,
                touchEventHandler
            )
        }
    }
}
+11 −13
Original line number Diff line number Diff line
@@ -233,6 +233,7 @@ import com.android.systemui.tuner.TunerService;
import com.android.systemui.unfold.UnfoldLightRevealOverlayAnimation;
import com.android.systemui.unfold.UnfoldTransitionWallpaperController;
import com.android.systemui.unfold.config.UnfoldTransitionConfig;
import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
import com.android.systemui.util.WallpaperController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.MessageRouter;
@@ -525,6 +526,7 @@ public class StatusBar extends SystemUI implements
    private QSPanelController mQSPanelController;

    private final OperatorNameViewController.Factory mOperatorNameViewControllerFactory;
    private final PhoneStatusBarViewController.Factory mPhoneStatusBarViewControllerFactory;
    KeyguardIndicationController mKeyguardIndicationController;

    private View mReportRejectedTouch;
@@ -543,8 +545,8 @@ public class StatusBar extends SystemUI implements
    private final FeatureFlags mFeatureFlags;
    private final UnfoldTransitionConfig mUnfoldTransitionConfig;
    private final Lazy<UnfoldLightRevealOverlayAnimation> mUnfoldLightRevealOverlayAnimation;
    private final Lazy<NaturalRotationUnfoldProgressProvider> mNaturalUnfoldProgressProvider;
    private final Lazy<UnfoldTransitionWallpaperController> mUnfoldWallpaperController;
    private final Lazy<StatusBarMoveFromCenterAnimationController> mMoveFromCenterAnimation;
    private final WallpaperController mWallpaperController;
    private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
    private final MessageRouter mMessageRouter;
@@ -772,6 +774,7 @@ public class StatusBar extends SystemUI implements
            ExtensionController extensionController,
            UserInfoControllerImpl userInfoControllerImpl,
            OperatorNameViewController.Factory operatorNameViewControllerFactory,
            PhoneStatusBarViewController.Factory phoneStatusBarViewControllerFactory,
            PhoneStatusBarPolicy phoneStatusBarPolicy,
            KeyguardIndicationController keyguardIndicationController,
            DemoModeController demoModeController,
@@ -782,7 +785,7 @@ public class StatusBar extends SystemUI implements
            UnfoldTransitionConfig unfoldTransitionConfig,
            Lazy<UnfoldLightRevealOverlayAnimation> unfoldLightRevealOverlayAnimation,
            Lazy<UnfoldTransitionWallpaperController> unfoldTransitionWallpaperController,
            Lazy<StatusBarMoveFromCenterAnimationController> statusBarUnfoldAnimationController,
            Lazy<NaturalRotationUnfoldProgressProvider> naturalRotationUnfoldProgressProvider,
            WallpaperController wallpaperController,
            OngoingCallController ongoingCallController,
            SystemStatusAnimationScheduler animationScheduler,
@@ -812,6 +815,7 @@ public class StatusBar extends SystemUI implements
        mKeyguardStateController = keyguardStateController;
        mHeadsUpManager = headsUpManagerPhone;
        mOperatorNameViewControllerFactory = operatorNameViewControllerFactory;
        mPhoneStatusBarViewControllerFactory = phoneStatusBarViewControllerFactory;
        mKeyguardIndicationController = keyguardIndicationController;
        mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
        mDynamicPrivacyController = dynamicPrivacyController;
@@ -879,9 +883,9 @@ public class StatusBar extends SystemUI implements
        mBrightnessSliderFactory = brightnessSliderFactory;
        mUnfoldTransitionConfig = unfoldTransitionConfig;
        mUnfoldLightRevealOverlayAnimation = unfoldLightRevealOverlayAnimation;
        mNaturalUnfoldProgressProvider = naturalRotationUnfoldProgressProvider;
        mUnfoldWallpaperController = unfoldTransitionWallpaperController;
        mWallpaperController = wallpaperController;
        mMoveFromCenterAnimation = statusBarUnfoldAnimationController;
        mOngoingCallController = ongoingCallController;
        mAnimationScheduler = animationScheduler;
        mStatusBarLocationPublisher = locationPublisher;
@@ -1077,6 +1081,7 @@ public class StatusBar extends SystemUI implements
        if (mUnfoldTransitionConfig.isEnabled()) {
            mUnfoldLightRevealOverlayAnimation.get().init();
            mUnfoldWallpaperController.get().init();
            mNaturalUnfoldProgressProvider.get().init();
        }

        mPluginManager.addPluginListener(
@@ -1178,16 +1183,9 @@ public class StatusBar extends SystemUI implements

                    mNotificationPanelViewController.setBar(mStatusBarView);

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

                    mBatteryMeterViewController = new BatteryMeterViewController(
+26 −21
Original line number Diff line number Diff line
@@ -20,43 +20,48 @@ 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.UNFOLD_STATUS_BAR
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import javax.inject.Inject
import javax.inject.Named

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

    private lateinit var moveFromCenterAnimator: UnfoldMoveFromCenterAnimator
    private val transitionListener = TransitionListener()
    private var moveFromCenterAnimator: UnfoldMoveFromCenterAnimator? = null

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

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

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

            override fun onTransitionFinished() {
                moveFromCenterAnimator.onTransitionFinished()
                moveFromCenterAnimator.clearRegisteredViews()
        progressProvider.addCallback(transitionListener)
    }

            override fun onTransitionProgress(progress: Float) {
                moveFromCenterAnimator.onTransitionProgress(progress)
            }
        })
    fun onViewDetached() {
        progressProvider.removeCallback(transitionListener)
        moveFromCenterAnimator?.clearRegisteredViews()
        moveFromCenterAnimator = null
    }

    fun onStatusBarWidthChanged() {
        moveFromCenterAnimator.updateViewPositions()
        moveFromCenterAnimator?.updateDisplayProperties()
        moveFromCenterAnimator?.updateViewPositions()
    }

    private inner class TransitionListener : TransitionProgressListener {
        override fun onTransitionProgress(progress: Float) {
            moveFromCenterAnimator?.onTransitionProgress(progress)
        }
    }
}
Loading