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

Commit 52ff84db authored by Mike Schneider's avatar Mike Schneider Committed by Automerger Merge Worker
Browse files

Merge "Add jank CUJ instrumentation to DialogLaunchAnimator" into tm-qpr-dev am: 4b175024

parents b3368e55 4b175024
Loading
Loading
Loading
Loading
+46 −16
Original line number Diff line number Diff line
@@ -34,6 +34,9 @@ import android.view.WindowInsets
import android.view.WindowManager
import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
import android.widget.FrameLayout
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.jank.InteractionJankMonitor.Configuration
import com.android.internal.jank.InteractionJankMonitor.CujType
import kotlin.math.roundToInt

private const val TAG = "DialogLaunchAnimator"
@@ -50,6 +53,7 @@ private const val TAG = "DialogLaunchAnimator"
 */
class DialogLaunchAnimator @JvmOverloads constructor(
    private val dreamManager: IDreamManager,
    private val interactionJankMonitor: InteractionJankMonitor,
    private val launchAnimator: LaunchAnimator = LaunchAnimator(TIMINGS, INTERPOLATORS),
    private val isForTesting: Boolean = false
) {
@@ -89,12 +93,14 @@ class DialogLaunchAnimator @JvmOverloads constructor(
    fun showFromView(
        dialog: Dialog,
        view: View,
        animateBackgroundBoundsChange: Boolean = false
        cuj: DialogCuj? = null,
        animateBackgroundBoundsChange: Boolean = false,
    ) {
        if (Looper.myLooper() != Looper.getMainLooper()) {
            throw IllegalStateException(
                "showFromView must be called from the main thread and dialog must be created in " +
                    "the main thread")
                    "the main thread"
            )
        }

        // If the view we are launching from belongs to another dialog, then this means the caller
@@ -115,12 +121,14 @@ class DialogLaunchAnimator @JvmOverloads constructor(
        val animatedDialog = AnimatedDialog(
            launchAnimator,
            dreamManager,
            interactionJankMonitor,
            animateFrom,
            onDialogDismissed = { openedDialogs.remove(it) },
            dialog = dialog,
            animateBackgroundBoundsChange,
            animatedParent,
                isForTesting
            isForTesting,
            cuj
        )

        openedDialogs.add(animatedDialog)
@@ -143,8 +151,9 @@ class DialogLaunchAnimator @JvmOverloads constructor(
            ?.dialogContentWithBackground
            ?: throw IllegalStateException(
                "The animateFrom dialog was not animated using " +
                    "DialogLaunchAnimator.showFrom(View|Dialog)")
        showFromView(dialog, view, animateBackgroundBoundsChange)
                    "DialogLaunchAnimator.showFrom(View|Dialog)"
            )
        showFromView(dialog, view, animateBackgroundBoundsChange = animateBackgroundBoundsChange)
    }

    /**
@@ -270,9 +279,17 @@ class DialogLaunchAnimator @JvmOverloads constructor(
    }
}

/**
 * The CUJ interaction associated with opening the dialog.
 *
 * The optional tag indicates the specific dialog being opened.
 */
data class DialogCuj(@CujType val cujType: Int, val tag: String? = null)

private class AnimatedDialog(
    private val launchAnimator: LaunchAnimator,
    private val dreamManager: IDreamManager,
    private val interactionJankMonitor: InteractionJankMonitor,

    /** The view that triggered the dialog after being tapped. */
    var touchSurface: View,
@@ -295,7 +312,10 @@ private class AnimatedDialog(
    /**
     * Whether synchronization should be disabled, which can be useful if we are running in a test.
     */
    private val forceDisableSynchronization: Boolean
    private val forceDisableSynchronization: Boolean,

    /** Interaction to which the dialog animation is associated. */
    private val cuj: DialogCuj? = null
) {
    /**
     * The DecorView of this dialog window.
@@ -346,6 +366,14 @@ private class AnimatedDialog(
    private var decorViewLayoutListener: View.OnLayoutChangeListener? = null

    fun start() {
        if (cuj != null) {
            val config = Configuration.Builder.withView(cuj.cujType, touchSurface)
            if (cuj.tag != null) {
                config.setTag(cuj.tag)
            }
            interactionJankMonitor.begin(config)
        }

        // Create the dialog so that its onCreate() method is called, which usually sets the dialog
        // content.
        dialog.create()
@@ -432,7 +460,8 @@ private class AnimatedDialog(
            decorViewLayoutListener = View.OnLayoutChangeListener {
                    v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
                if (window.attributes.width != MATCH_PARENT ||
                    window.attributes.height != MATCH_PARENT) {
                    window.attributes.height != MATCH_PARENT
                ) {
                    // The dialog size changed, copy its size to dialogContentWithBackground and
                    // make the dialog window full screen again.
                    val layoutParams = dialogContentWithBackground.layoutParams
@@ -606,6 +635,7 @@ private class AnimatedDialog(
                    dialogContentWithBackground!!
                        .addOnLayoutChangeListener(backgroundLayoutListener)
                }
                cuj?.run { interactionJankMonitor.end(cujType) }
            }
        )
    }
+3 −1
Original line number Diff line number Diff line
@@ -175,7 +175,9 @@ public class DndTile extends QSTileImpl<BooleanState> {
                    mUiHandler.post(() -> {
                        Dialog dialog = makeZenModeDialog();
                        if (view != null) {
                            mDialogLaunchAnimator.showFromView(dialog, view, false);
                            mDialogLaunchAnimator.showFromView(dialog, view,
                                    /* cuj= */ null,
                                    /* animateBackgroundBoundsChange= */ false);
                        } else {
                            dialog.show();
                        }
+16 −5
Original line number Diff line number Diff line
@@ -19,7 +19,9 @@ import android.content.Context
import android.os.Handler
import android.util.Log
import android.view.View
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.UiEventLogger
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
@@ -45,6 +47,7 @@ class InternetDialogFactory @Inject constructor(
    private val keyguardStateController: KeyguardStateController
) {
    companion object {
        private const val INTERACTION_JANK_TAG = "internet"
        var internetDialog: InternetDialog? = null
    }

@@ -61,12 +64,20 @@ class InternetDialogFactory @Inject constructor(
            }
            return
        } else {
            internetDialog = InternetDialog(context, this, internetDialogController,
            internetDialog = InternetDialog(
                context, this, internetDialogController,
                canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler,
                    executor, keyguardStateController)
                executor, keyguardStateController
            )
            if (view != null) {
                dialogLaunchAnimator.showFromView(internetDialog!!, view,
                    animateBackgroundBoundsChange = true)
                dialogLaunchAnimator.showFromView(
                    internetDialog!!, view,
                    animateBackgroundBoundsChange = true,
                    cuj = DialogCuj(
                        InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
                        INTERACTION_JANK_TAG
                    )
                )
            } else {
                internetDialog?.show()
            }
+4 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.os.Handler;
import android.service.dreams.IDreamManager;

import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.statusbar.IStatusBarService;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.animation.ActivityLaunchAnimator;
@@ -317,7 +318,8 @@ public interface CentralSurfacesDependenciesModule {
     */
    @Provides
    @SysUISingleton
    static DialogLaunchAnimator provideDialogLaunchAnimator(IDreamManager dreamManager) {
        return new DialogLaunchAnimator(dreamManager);
    static DialogLaunchAnimator provideDialogLaunchAnimator(IDreamManager dreamManager,
            InteractionJankMonitor interactionJankMonitor) {
        return new DialogLaunchAnimator(dreamManager, interactionJankMonitor);
    }
}
+27 −3
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.WindowManager
import android.widget.LinearLayout
import androidx.test.filters.SmallTest
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.policy.DecorView
import com.android.systemui.SysuiTestCase
import junit.framework.Assert.assertEquals
@@ -29,6 +30,8 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit

@SmallTest
@@ -40,12 +43,14 @@ class DialogLaunchAnimatorTest : SysuiTestCase() {
    private val attachedViews = mutableSetOf<View>()

    @Mock lateinit var dreamManager: IDreamManager
    @Mock lateinit var interactionJankMonitor: InteractionJankMonitor
    @get:Rule val rule = MockitoJUnit.rule()

    @Before
    fun setUp() {
        dialogLaunchAnimator = DialogLaunchAnimator(
            dreamManager, launchAnimator, isForTesting = true)
            dreamManager, interactionJankMonitor, launchAnimator, isForTesting = true
        )
    }

    @After
@@ -90,7 +95,8 @@ class DialogLaunchAnimatorTest : SysuiTestCase() {

        // The dialog content is inside this fake window view.
        assertNotNull(
            dialogContentWithBackground.findViewByPredicate { it === dialog.contentView })
            dialogContentWithBackground.findViewByPredicate { it === dialog.contentView }
        )

        // Clicking the transparent background should dismiss the dialog.
        runOnMainThreadAndWaitForIdleSync {
@@ -161,6 +167,24 @@ class DialogLaunchAnimatorTest : SysuiTestCase() {
        assertNotEquals(0, dialog.window.attributes.windowAnimations)
    }

    @Test
    fun testCujSpecificationLogsInteraction() {
        val touchSurface = createTouchSurface()
        return runOnMainThreadAndWaitForIdleSync {
            val dialog = TestDialog(context)
            dialogLaunchAnimator.showFromView(
                dialog, touchSurface,
                cuj = DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN)
            )
        }

        verify(interactionJankMonitor).begin(
            any()
        )
        verify(interactionJankMonitor)
            .end(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN)
    }

    private fun createAndShowDialog(): TestDialog {
        val touchSurface = createTouchSurface()
        return runOnMainThreadAndWaitForIdleSync {
Loading