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

Commit f260376a authored by Johannes Gallmann's avatar Johannes Gallmann
Browse files

Fix broken CUJ tacking for CUJ_LPP_ASSIST_INVOCATION_EFFECT

This fixes the issue that the wrong Choreographer was used for the
vsync id. Since the animator runs in SystemUI, the vsyncId obtained from
the Choreographer from SystemUI needs to be used.

Secondly, for correct CUJ tracking, the handler from the Thread that
runs the animators needs to be passed to InteractionJankMonitor#begin.

Bug: 418136893
Test: TopLevelWindowEffectsTest
Test: Manual, i.e. verified that CUJ is correctly showing up in perfetto
      trace
Flag: com.android.systemui.shared.enable_lpp_assist_invocation_effect
Change-Id: I125d7b7e6236b0858c52490ffc361b2f1695767b
parent 2296d78a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.wm.shell.appzoomout;

import android.os.Handler;

import com.android.wm.shell.shared.annotations.ExternalThread;

/**
@@ -45,7 +47,9 @@ public interface AppZoomOut {
     * </ul>
     *
     * @param progress The progress to set the squeeze zoom effect to.
     * @param vsyncId The vsync id to align the frame to.
     * @param sysuiMainHandler The main handler from SystemUI (required for CUJ tracking)
     */
    void setTopLevelProgress(float progress);
    void setTopLevelProgress(float progress, long vsyncId, Handler sysuiMainHandler);

}
+9 −6
Original line number Diff line number Diff line
@@ -84,12 +84,12 @@ public class AppZoomOutController implements RemoteCallable<AppZoomOutController
    public static AppZoomOutController create(Context context, ShellInit shellInit,
            ShellTaskOrganizer shellTaskOrganizer, DisplayController displayController,
            DisplayLayout displayLayout, @ShellMainThread ShellExecutor mainExecutor,
            @ShellMainThread Handler mainHandler, InteractionJankMonitor interactionJankMonitor) {
            InteractionJankMonitor interactionJankMonitor) {
        AppZoomOutDisplayAreaOrganizer appDisplayAreaOrganizer = new AppZoomOutDisplayAreaOrganizer(
                context, displayLayout, mainExecutor);
        TopLevelZoomOutDisplayAreaOrganizer topLevelDisplayAreaOrganizer =
                new TopLevelZoomOutDisplayAreaOrganizer(displayLayout, context, mainExecutor,
                        mainHandler, interactionJankMonitor);
                        interactionJankMonitor);
        return new AppZoomOutController(context, shellInit, shellTaskOrganizer, displayController,
                appDisplayAreaOrganizer, topLevelDisplayAreaOrganizer, mainExecutor);
    }
@@ -142,10 +142,12 @@ public class AppZoomOutController implements RemoteCallable<AppZoomOutController
     * {@link DisplayAreaOrganizer#FEATURE_WINDOWED_MAGNIFICATION} and applies a cropping.
     *
     * @param progress progress to be applied to the top-level zoom effect.
     * @param vsyncId The vsync id to align the frame to.
     * @param sysuiMainHandler The main handler from SystemUI (required for CUJ tracking)
     */
    private void setTopLevelProgress(float progress) {
    private void setTopLevelProgress(float progress, long vsyncId, Handler sysuiMainHandler) {
        if (enableLppAssistInvocationEffect()) {
            mTopLevelDisplayAreaOrganizer.setProgress(progress);
            mTopLevelDisplayAreaOrganizer.setProgress(progress, vsyncId, sysuiMainHandler);
        }
    }

@@ -201,8 +203,9 @@ public class AppZoomOutController implements RemoteCallable<AppZoomOutController
        }

        @Override
        public void setTopLevelProgress(float progress) {
            mMainExecutor.execute(() -> AppZoomOutController.this.setTopLevelProgress(progress));
        public void setTopLevelProgress(float progress, long vsyncId, Handler sysuiMainHandler) {
            mMainExecutor.execute(() -> AppZoomOutController.this.setTopLevelProgress(progress,
                    vsyncId, sysuiMainHandler));
        }
    }
}
+11 −12
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.wm.shell.appzoomout
import android.content.Context
import android.os.Handler
import android.util.ArrayMap
import android.view.Choreographer
import android.view.Display
import android.view.SurfaceControl
import android.window.DisplayAreaInfo
@@ -42,7 +41,6 @@ class TopLevelZoomOutDisplayAreaOrganizer(
    displayLayout: DisplayLayout,
    private val context: Context,
    mainExecutor: Executor,
    private val mainHandler: Handler,
    private val interactionJankMonitor: InteractionJankMonitor,
) : DisplayAreaOrganizer(mainExecutor) {

@@ -86,32 +84,33 @@ class TopLevelZoomOutDisplayAreaOrganizer(
        reset()
    }

    fun setProgress(progress: Float) {
    fun setProgress(progress: Float, vsyncId: Long, sysuiMainHandler: Handler?) {
        if (mProgress == progress) {
            return
        }

        updateCuj(lastProgress = mProgress, progress = progress)
        updateCuj(lastProgress = mProgress, progress = progress, sysuiMainHandler = sysuiMainHandler)
        mProgress = progress
        apply()
        apply(vsyncId)
    }

    private fun apply() {
    private fun apply(vsyncId: Long) {
        val tx = SurfaceControl.Transaction()
        mDisplayAreaTokenMap.values.forEach { leash: SurfaceControl ->
            updateSurface(tx, leash, mProgress)
            updateSurface(tx, leash, mProgress, vsyncId)
        }
        tx.apply()
    }

    private fun reset() {
        setProgress(0f)
        setProgress(0f, 0, null)
    }

    private fun updateSurface(
        tx: SurfaceControl.Transaction,
        leash: SurfaceControl,
        progress: Float
        progress: Float,
        vsyncId: Long,
    ) {
        if (progress == 0f) {
            // Reset when scale is set back to 0.
@@ -168,10 +167,10 @@ class TopLevelZoomOutDisplayAreaOrganizer(
            .setCornerRadius(leash, cornerRadius * zoomOutScale)
            .setScale(leash, zoomOutScale, zoomOutScale)
            .setPosition(leash, positionXOffset, positionYOffset)
            .setFrameTimelineVsync(Choreographer.getInstance().vsyncId)
            .setFrameTimelineVsync(vsyncId)
    }

    private fun updateCuj(lastProgress: Float, progress: Float) {
    private fun updateCuj(lastProgress: Float, progress: Float, sysuiMainHandler: Handler?) {
        // TODO(b/418136893): Send clearer start/cancel/end signals from SysUI instead
        if (progress == 1f) {
            // If the animation reaches a progress of 1f, it means that assistant is being launched
@@ -186,7 +185,7 @@ class TopLevelZoomOutDisplayAreaOrganizer(
                interactionJankMonitor.begin(
                    it,
                    context,
                    mainHandler,
                    sysuiMainHandler,
                    CUJ_LPP_ASSIST_INVOCATION_EFFECT
                )
            }
+1 −3
Original line number Diff line number Diff line
@@ -1747,11 +1747,9 @@ public abstract class WMShellModule {
            DisplayController displayController,
            DisplayLayout displayLayout,
            @ShellMainThread ShellExecutor mainExecutor,
            @ShellMainThread Handler mainHandler,
            InteractionJankMonitor interactionJankMonitor) {
        return AppZoomOutController.create(context, shellInit, shellTaskOrganizer,
                displayController, displayLayout, mainExecutor, mainHandler,
                interactionJankMonitor);
                displayController, displayLayout, mainExecutor, interactionJankMonitor);
    }

    //
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.topwindoweffects

import android.os.VibrationEffect
import android.os.fakeHandler
import android.testing.TestableLooper.RunWithLooper
import androidx.core.animation.AnimatorTestRule
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -97,6 +98,7 @@ class TopLevelWindowEffectsTest : SysuiTestCase() {
                notificationShadeWindowController = notificationShadeWindowController,
                topUiController = mockTopUiController,
                mainExecutor = fakeExecutor,
                mainHandler = kosmos.fakeHandler,
            )
        }

Loading