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

Commit c2b59843 authored by Jeremy Sim's avatar Jeremy Sim
Browse files

Use fade-in launcher for app pair launches from in-app taskbar

This CL temporarily patches a crash in this situation:

Inside of an app > Launch an unrelated app pair from Taskbar > Crash

The crash occurs because TaskbarActivityContext can't create a launcher animation (because Launcher isn't running). A different launch animation is needed for this case (similar to single apps), but for now, falling back to the fade-in launch at least allows the user to proceed without a crash.

Bug: 316485863
Test: Enter an app, launch an unrelated app pair, no crash
Flag: ACONFIG com.android.wm.shell.enable_app_pairs DEVELOPMENT
Change-Id: I72b2956b5b44616367e24263f2287824ee1e8212
parent e281a5fb
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.statehandlers.DepthController
import com.android.launcher3.statemanager.StateManager
import com.android.launcher3.statemanager.StatefulActivity
import com.android.launcher3.taskbar.TaskbarActivityContext
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource
import com.android.launcher3.views.BaseDragLayer
import com.android.quickstep.TaskViewUtils
@@ -390,6 +391,14 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
                "trying to launch an app pair icon, but encountered an unexpected null"
            }

            // If launching an app pair from Taskbar inside of an app context, use fade-in animation
            // TODO (b/316485863): Replace with desired app pair launch animation
            if (launchingIconView.context is TaskbarActivityContext) {
                composeFadeInSplitLaunchAnimator(
                    initialTaskId, secondTaskId, info, t, finishCallback)
                return
            }

            composeIconSplitLaunchAnimator(launchingIconView, info, t, finishCallback)
        } else {
            // Fallback case: simple fade-in animation
+32 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.quickstep.util

import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.view.ContextThemeWrapper
import android.view.SurfaceControl.Transaction
import android.view.View
import android.window.TransitionInfo
@@ -26,6 +27,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.launcher3.apppairs.AppPairIcon
import com.android.launcher3.statehandlers.DepthController
import com.android.launcher3.statemanager.StateManager
import com.android.launcher3.taskbar.TaskbarActivityContext
import com.android.launcher3.util.SplitConfigurationOptions
import com.android.quickstep.views.GroupedTaskView
import com.android.quickstep.views.IconView
@@ -64,6 +66,8 @@ class SplitAnimationControllerTest {
    private val mockTaskIdAttributeContainer: TaskIdAttributeContainer = mock()
    // AppPairIcon
    private val mockAppPairIcon: AppPairIcon = mock()
    private val mockContextThemeWrapper: ContextThemeWrapper = mock()
    private val mockTaskbarActivityContext: TaskbarActivityContext = mock()

    // SplitSelectSource
    private val splitSelectSource: SplitConfigurationOptions.SplitSelectSource = mock()
@@ -247,6 +251,7 @@ class SplitAnimationControllerTest {
    @Test
    fun playsAppropriateSplitLaunchAnimation_playsIconLaunchCorrectly() {
        val spySplitAnimationController = spy(splitAnimationController)
        whenever(mockAppPairIcon.context).thenReturn(mockContextThemeWrapper)
        doNothing()
            .whenever(spySplitAnimationController)
            .composeIconSplitLaunchAnimator(any(), any(), any(), any())
@@ -270,6 +275,33 @@ class SplitAnimationControllerTest {
            .composeIconSplitLaunchAnimator(any(), any(), any(), any())
    }

    @Test
    fun playsAppropriateSplitLaunchAnimation_playsIconLaunchFromTaskbarContextCorrectly() {
        val spySplitAnimationController = spy(splitAnimationController)
        whenever(mockAppPairIcon.context).thenReturn(mockTaskbarActivityContext)
        doNothing()
            .whenever(spySplitAnimationController)
            .composeFadeInSplitLaunchAnimator(any(), any(), any(), any(), any())

        spySplitAnimationController.playSplitLaunchAnimation(
            null /* launchingTaskView */,
            mockAppPairIcon,
            taskId,
            taskId2,
            null /* apps */,
            null /* wallpapers */,
            null /* nonApps */,
            stateManager,
            depthController,
            transitionInfo,
            transaction,
            {} /* finishCallback */
        )

        verify(spySplitAnimationController)
            .composeFadeInSplitLaunchAnimator(any(), any(), any(), any(), any())
    }

    @Test
    fun playsAppropriateSplitLaunchAnimation_playsFadeInLaunchCorrectly() {
        val spySplitAnimationController = spy(splitAnimationController)