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

Commit ff160c51 authored by randypfohl's avatar randypfohl
Browse files

decoupling task animation lifecycle from recents lifecycle

this will fix a few bugs but create acouple others. Luckily this is all behind a flag for now but will prevent us building on broken code

Test: Built locally and tested

Flag: com.android.launcher3.enable_fallback_overview_in_window

Bug:292269949

Change-Id: Ifd147d6f3dd3234dfb1afe369f83c241a205c6af
parent c8d1465a
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import com.android.launcher3.taskbar.TaskbarUIController;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.fallback.window.RecentsWindowManager;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
+1 −5
Original line number Diff line number Diff line
@@ -298,7 +298,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
                && Flags.enableFallbackOverviewInWindow()){
            mRecentsAnimationStartPending =
                    getSystemUiProxy().startRecentsActivity(intent, options, mCallbacks);
            mRecentsWindowsManager.startRecentsWindow();
            mRecentsWindowsManager.startRecentsWindow(mCallbacks);
        } else {
            options.setPendingIntentBackgroundActivityStartMode(
                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS);
@@ -485,10 +485,6 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
        mTargets = null;
        mLastGestureState = null;
        mLastAppearedTaskTargets = null;

        if(Flags.enableFallbackOverviewInWindow()) {
            mRecentsWindowsManager.cleanup();
        }
    }

    @Nullable
+72 −17
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ import com.android.launcher3.views.BaseDragLayer
import com.android.launcher3.views.ScrimView
import com.android.quickstep.FallbackWindowInterface
import com.android.quickstep.OverviewComponentObserver
import com.android.quickstep.RecentsAnimationCallbacks
import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener
import com.android.quickstep.RecentsAnimationController
import com.android.quickstep.RecentsModel
import com.android.quickstep.RemoteAnimationTargets
import com.android.quickstep.SystemUiProxy
@@ -66,18 +69,25 @@ import com.android.quickstep.util.TISBindHelper
import com.android.quickstep.views.OverviewActionsView
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsViewContainer
import com.android.systemui.shared.recents.model.ThumbnailData
import com.android.systemui.shared.system.TaskStackChangeListener
import com.android.systemui.shared.system.TaskStackChangeListeners
import java.util.function.Predicate

/**
 * Class that will manage RecentsView lifecycle within a window and interface correctly where
 * needed. This allows us to run RecentsView in a window where needed. todo: b/365776320,
 * b/365777482
 * needed. This allows us to run RecentsView in a window where needed.
 *
 * todo: b/365776320,b/365777482
 *
 * To add new protologs, see [RecentsWindowProtoLogProxy]. To enable logging to logcat, see
 * [QuickstepProtoLogGroup.Constants.DEBUG_RECENTS_WINDOW]
 */
class RecentsWindowManager(context: Context) :
    RecentsWindowContext(context), RecentsViewContainer, StatefulContainer<RecentsState> {
    RecentsWindowContext(context),
    RecentsViewContainer,
    StatefulContainer<RecentsState>,
    RecentsAnimationListener {

    companion object {
        private const val HOME_APPEAR_DURATION: Long = 250
@@ -98,22 +108,37 @@ class RecentsWindowManager(context: Context) :
    private var actionsView: OverviewActionsView<*>? = null
    private var scrimView: ScrimView? = null

    private var isShown = false
    private var callbacks: RecentsAnimationCallbacks? = null

    private var tisBindHelper: TISBindHelper = TISBindHelper(this) {}

    // Callback array that corresponds to events defined in @ActivityEvent
    private val mEventCallbacks =
        arrayOf(RunnableList(), RunnableList(), RunnableList(), RunnableList())
        listOf(RunnableList(), RunnableList(), RunnableList(), RunnableList())
    private var onInitListener: Predicate<Boolean>? = null

    private val taskStackChangeListener =
        object : TaskStackChangeListener {
            override fun onTaskMovedToFront(taskId: Int) {
                if ((isShowing() && isInState(DEFAULT))) {
                    // handling state where we end recents animation by swiping livetile away
                    // TODO: animate this switch.
                    cleanupRecentsWindow()
                }
            }
        }

    init {
        FallbackWindowInterface.init(this)
        TaskStackChangeListeners.getInstance().registerTaskStackListener(taskStackChangeListener)
    }

    override fun destroy() {
        super.destroy()
        cleanupRecentsWindow()
        FallbackWindowInterface.getInstance()?.destroy()
        TaskStackChangeListeners.getInstance().unregisterTaskStackListener(taskStackChangeListener)
        callbacks?.removeListener(this)
    }

    override fun startHome() {
@@ -135,6 +160,7 @@ class RecentsWindowManager(context: Context) :
                ),
            )
        OverviewComponentObserver.startHomeIntentSafely(this, options.toBundle(), TAG)
        stateManager.moveToRestState()
    }

    private val mAnimationToHomeFactory =
@@ -165,28 +191,34 @@ class RecentsWindowManager(context: Context) :
                this@RecentsWindowManager,
                {
                    getStateManager().goToState(BG_LAUNCHER, false)
                    cleanup()
                    cleanupRecentsWindow()
                },
                true, /* skipFirstFrame */
            )
        }

    fun cleanup() {
        RecentsWindowProtoLogProxy.logCleanup(isShown)
        if (isShown) {
    private fun cleanupRecentsWindow() {
        RecentsWindowProtoLogProxy.logCleanup(isShowing())
        if (isShowing()) {
            windowManager.removeViewImmediate(windowView)
            isShown = false
        }
        stateManager.moveToRestState()
        callbacks?.removeListener(this)
    }

    fun startRecentsWindow() {
        RecentsWindowProtoLogProxy.logStartRecentsWindow(isShown, windowView == null)
        if (isShown) return
    private fun isShowing(): Boolean {
        return windowView?.parent != null
    }

    fun startRecentsWindow(callbacks: RecentsAnimationCallbacks? = null) {
        RecentsWindowProtoLogProxy.logStartRecentsWindow(isShowing(), windowView == null)
        if (isShowing()) {
            return
        }
        if (windowView == null) {
            windowView = layoutInflater.inflate(R.layout.fallback_recents_activity, null)
        }
        windowManager.addView(windowView, windowLayoutParams)
        isShown = true

        windowView?.systemUiVisibility =
            (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
@@ -215,6 +247,25 @@ class RecentsWindowManager(context: Context) :

        mSystemUiController = SystemUiController(windowView)
        onInitListener?.test(true)

        this.callbacks = callbacks
        callbacks?.addListener(this)
    }

    override fun onRecentsAnimationCanceled(thumbnailDatas: HashMap<Int, ThumbnailData>) {
        super.onRecentsAnimationCanceled(thumbnailDatas)
        recentAnimationStopped()
    }

    override fun onRecentsAnimationFinished(controller: RecentsAnimationController) {
        super.onRecentsAnimationFinished(controller)
        recentAnimationStopped()
    }

    private fun recentAnimationStopped() {
        if (isInState(BACKGROUND_APP)) {
            cleanupRecentsWindow()
        }
    }

    override fun canStartHomeSafely(): Boolean {
@@ -246,14 +297,18 @@ class RecentsWindowManager(context: Context) :
        return stateManager.state == state
    }

    override fun onStateSetStart(state: RecentsState?) {
    override fun onStateSetStart(state: RecentsState) {
        super.onStateSetStart(state)
        RecentsWindowProtoLogProxy.logOnStateSetStart(getStateName(state))
    }

    override fun onStateSetEnd(state: RecentsState?) {
    override fun onStateSetEnd(state: RecentsState) {
        super.onStateSetEnd(state)
        RecentsWindowProtoLogProxy.logOnStateSetEnd(getStateName(state))

        if (state == HOME || state == BG_LAUNCHER) {
            cleanupRecentsWindow()
        }
    }

    private fun getStateName(state: RecentsState?): String {
@@ -319,7 +374,7 @@ class RecentsWindowManager(context: Context) :
    }

    override fun isStarted(): Boolean {
        return isShown
        return isShowing() && isInState(DEFAULT)
    }

    /** Adds a callback for the provided activity event */