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

Commit 594326bf authored by Sergey Pinkevich's avatar Sergey Pinkevich
Browse files

Add tracing for closing task CUJ in Desktop Windowing

Bug: 339586278
Test: record perfetto trace while performing closing task
Flag: NONE new perfetto instrumentation

Change-Id: I4ab322b9690b5161198c5d0c71d6cc2588599429
parent d2d5c500
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -265,8 +265,17 @@ public class Cuj {
     */
    public static final int CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS = 121;

    /**
     * Track closing task in Desktop Windowing.
     *
     * <p> Tracking begins when the CloseDesktopTaskTransitionHandler in Launcher starts
     * animating the task closure. This is triggered when the close button in the app header is
     * clicked on a desktop window. </p>
     */
    public static final int CUJ_DESKTOP_MODE_CLOSE_TASK = 122;

    // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
    @VisibleForTesting static final int LAST_CUJ = CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS;
    @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_CLOSE_TASK;

    /** @hide */
    @IntDef({
@@ -379,7 +388,8 @@ public class Cuj {
            CUJ_DESKTOP_MODE_SNAP_RESIZE,
            CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW,
            CUJ_DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU,
            CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS
            CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS,
            CUJ_DESKTOP_MODE_CLOSE_TASK
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface CujType {}
@@ -503,6 +513,7 @@ public class Cuj {
        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_UNMAXIMIZE_WINDOW;
        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU;
        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OVERVIEW_TASK_DISMISS;
        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_CLOSE_TASK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_CLOSE_TASK;
    }

    private Cuj() {
@@ -741,6 +752,8 @@ public class Cuj {
                return "DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU";
            case CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS:
                return "LAUNCHER_OVERVIEW_TASK_DISMISS";
            case CUJ_DESKTOP_MODE_CLOSE_TASK:
                return "DESKTOP_MODE_CLOSE_TASK";
        }
        return "UNKNOWN";
    }
+3 −2
Original line number Diff line number Diff line
@@ -1027,8 +1027,9 @@ public abstract class WMShellModule {
    static CloseDesktopTaskTransitionHandler provideCloseDesktopTaskTransitionHandler(
            Context context,
            @ShellMainThread ShellExecutor mainExecutor,
            @ShellAnimationThread ShellExecutor animExecutor) {
        return new CloseDesktopTaskTransitionHandler(context, mainExecutor, animExecutor);
            @ShellAnimationThread ShellExecutor animExecutor,
            @ShellMainThread Handler handler) {
        return new CloseDesktopTaskTransitionHandler(context, mainExecutor, animExecutor, handler);
    }

    @WMSingleton
+23 −6
Original line number Diff line number Diff line
@@ -23,8 +23,10 @@ import android.animation.ValueAnimator
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.content.Context
import android.graphics.Rect
import android.os.Handler
import android.os.IBinder
import android.util.TypedValue
import android.view.Choreographer
import android.view.SurfaceControl.Transaction
import android.view.WindowManager
import android.window.TransitionInfo
@@ -32,7 +34,10 @@ import android.window.TransitionRequestInfo
import android.window.WindowContainerTransaction
import androidx.core.animation.addListener
import com.android.app.animation.Interpolators
import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_CLOSE_TASK
import com.android.internal.jank.InteractionJankMonitor
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.transition.Transitions
import java.util.function.Supplier

@@ -44,9 +49,11 @@ constructor(
    private val mainExecutor: ShellExecutor,
    private val animExecutor: ShellExecutor,
    private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() },
    @ShellMainThread private val handler: Handler,
) : Transitions.TransitionHandler {

    private val runningAnimations = mutableMapOf<IBinder, List<Animator>>()
    private val interactionJankMonitor = InteractionJankMonitor.getInstance()

    /** Returns null, as it only handles transitions started from Shell. */
    override fun handleRequest(
@@ -71,18 +78,27 @@ constructor(
                    // All animations completed, finish the transition
                    runningAnimations.remove(transition)
                    finishCallback.onTransitionFinished(/* wct= */ null)
                    interactionJankMonitor.end(CUJ_DESKTOP_MODE_CLOSE_TASK)
                }
            }
        }
        animations +=
            info.changes
                .filter {
        val closingChanges =
            info.changes.filter {
                it.mode == WindowManager.TRANSIT_CLOSE &&
                    it.taskInfo?.windowingMode == WINDOWING_MODE_FREEFORM
            }
                .map { createCloseAnimation(it, finishTransaction, onAnimFinish) }
        animations +=
            closingChanges.map { createCloseAnimation(it, finishTransaction, onAnimFinish) }
        if (animations.isEmpty()) return false
        runningAnimations[transition] = animations
        closingChanges.lastOrNull()?.leash?.let { lastChangeLeash ->
            interactionJankMonitor.begin(
                lastChangeLeash,
                context,
                handler,
                CUJ_DESKTOP_MODE_CLOSE_TASK,
            )
        }
        animExecutor.execute { animations.forEach(Animator::start) }
        return true
    }
@@ -127,6 +143,7 @@ constructor(
                    .get()
                    .setPosition(change.leash, animBounds.left.toFloat(), animBounds.top.toFloat())
                    .setScale(change.leash, animScale, animScale)
                    .setFrameTimeline(Choreographer.getInstance().vsyncId)
                    .apply()
            }
        }
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.app.WindowConfiguration.WindowingMode
import android.os.Handler
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.SurfaceControl
@@ -52,6 +53,7 @@ class CloseDesktopTaskTransitionHandlerTest : ShellTestCase() {

    @Mock lateinit var testExecutor: ShellExecutor
    @Mock lateinit var closingTaskLeash: SurfaceControl
    @Mock lateinit var mockHandler: Handler

    private val transactionSupplier = Supplier { mock<SurfaceControl.Transaction>() }

@@ -65,6 +67,7 @@ class CloseDesktopTaskTransitionHandlerTest : ShellTestCase() {
                testExecutor,
                testExecutor,
                transactionSupplier,
                mockHandler,
            )
    }