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

Commit 5c916ce6 authored by Matt Pietal's avatar Matt Pietal
Browse files

Realign lockscreen CUJs with transitions/animators

The underlying animator that controls the UI has changed.
Realign the CUJs with this animator.

This may cause some changes in jank metrics.

Bug: 393083978
Test: use perfetto to look at lockscreen CUJs
Flag: EXEMPT jank monitoring
Change-Id: I1916073baf4107f8b84dc24302db36771c57fe84
parent abef94fb
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -375,7 +375,6 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
        SystemClock systemClock = new FakeSystemClock();
        mStatusBarStateController = new StatusBarStateControllerImpl(
                mUiEventLogger,
                () -> mKosmos.getInteractionJankMonitor(),
                mJavaAdapter,
                () -> mKeyguardInteractor,
                () -> mKeyguardTransitionInteractor,
@@ -456,7 +455,6 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
                        mock(HeadsUpManager.class),
                        new StatusBarStateControllerImpl(
                                new UiEventLoggerFake(),
                                () -> mKosmos.getInteractionJankMonitor(),
                                mJavaAdapter,
                                () -> mKeyguardInteractor,
                                () -> mKeyguardTransitionInteractor,
+0 −2
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteract
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.parameterizeSceneContainerFlag
import com.android.systemui.jank.interactionJankMonitor
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
@@ -113,7 +112,6 @@ class StatusBarStateControllerImplTest(flags: FlagsParameterization) : SysuiTest
            object :
                StatusBarStateControllerImpl(
                    uiEventLogger,
                    { kosmos.interactionJankMonitor },
                    JavaAdapter(testScope.backgroundScope),
                    { kosmos.keyguardInteractor },
                    { kosmos.keyguardTransitionInteractor },
+22 −2
Original line number Diff line number Diff line
@@ -29,12 +29,14 @@ import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInte
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.domain.interactor.WallpaperFocalAreaInteractor
import com.android.systemui.keyguard.ui.binder.KeyguardBlueprintViewBinder
import com.android.systemui.keyguard.ui.binder.KeyguardJankBinder
import com.android.systemui.keyguard.ui.binder.KeyguardRootViewBinder
import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder
import com.android.systemui.keyguard.ui.view.KeyguardIndicationArea
import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardJankViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel
@@ -65,6 +67,7 @@ class KeyguardViewConfigurator
constructor(
    private val keyguardRootView: KeyguardRootView,
    private val keyguardRootViewModel: KeyguardRootViewModel,
    private val keyguardJankViewModel: KeyguardJankViewModel,
    private val screenOffAnimationController: ScreenOffAnimationController,
    private val occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel,
    private val chipbarCoordinator: ChipbarCoordinator,
@@ -93,9 +96,11 @@ constructor(
) : CoreStartable {

    private var rootViewHandle: DisposableHandle? = null
    private var jankHandle: DisposableHandle? = null

    override fun start() {
        bindKeyguardRootView()
        bindJankViewModel()
        initializeViews()

        if (lightRevealMigration()) {
@@ -145,11 +150,9 @@ constructor(
                clockInteractor,
                wallpaperFocalAreaInteractor,
                keyguardClockViewModel,
                interactionJankMonitor,
                deviceEntryHapticsInteractor,
                vibratorHelper,
                falsingManager,
                keyguardViewMediator,
                statusBarKeyguardViewManager,
                mainDispatcher,
                msdlPlayer,
@@ -157,5 +160,22 @@ constructor(
            )
    }

    private fun bindJankViewModel() {
        if (SceneContainerFlag.isEnabled) {
            return
        }

        jankHandle?.dispose()
        jankHandle =
            KeyguardJankBinder.bind(
                keyguardRootView,
                keyguardJankViewModel,
                interactionJankMonitor,
                clockInteractor,
                keyguardViewMediator,
                mainDispatcher,
            )
    }

    fun getKeyguardRootView() = keyguardRootView
}
+96 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.keyguard.ui.binder

import android.view.ViewGroup
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.jank.Cuj.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD
import com.android.internal.jank.Cuj.CUJ_LOCKSCREEN_TRANSITION_TO_AOD
import com.android.internal.jank.Cuj.CUJ_SCREEN_OFF_SHOW_AOD
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.viewmodel.KeyguardJankViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi

/** Jank monitoring related to keyguard and transitions. */
@OptIn(ExperimentalCoroutinesApi::class)
object KeyguardJankBinder {
    @JvmStatic
    fun bind(
        view: ViewGroup,
        viewModel: KeyguardJankViewModel,
        jankMonitor: InteractionJankMonitor?,
        clockInteractor: KeyguardClockInteractor,
        keyguardViewMediator: KeyguardViewMediator?,
        mainImmediateDispatcher: CoroutineDispatcher,
    ): DisposableHandle? {
        if (jankMonitor == null) {
            return null
        }

        fun processStep(step: TransitionStep, cuj: Int) {
            val clockId = clockInteractor.renderedClockId
            when (step.transitionState) {
                TransitionState.STARTED -> {
                    val builder =
                        InteractionJankMonitor.Configuration.Builder.withView(cuj, view)
                            .setTag(clockId)
                    jankMonitor.begin(builder)
                }

                TransitionState.CANCELED -> jankMonitor.cancel(cuj)

                TransitionState.FINISHED -> jankMonitor.end(cuj)

                TransitionState.RUNNING -> Unit
            }
        }

        return view.repeatWhenAttached(mainImmediateDispatcher) {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                launch {
                    viewModel.goneToAodTransition.collect {
                        processStep(it, CUJ_SCREEN_OFF_SHOW_AOD)
                        if (it.transitionState == TransitionState.FINISHED) {
                            keyguardViewMediator?.maybeHandlePendingLock()
                        }
                    }
                }

                launch {
                    viewModel.lockscreenToAodTransition.collect {
                        processStep(it, CUJ_LOCKSCREEN_TRANSITION_TO_AOD)
                    }
                }

                launch {
                    viewModel.aodToLockscreenTransition.collect {
                        processStep(it, CUJ_LOCKSCREEN_TRANSITION_FROM_AOD)
                    }
                }
            }
        }
    }
}
+0 −35
Original line number Diff line number Diff line
@@ -37,8 +37,6 @@ import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD
import com.android.keyguard.AuthInteractionProperties
import com.android.systemui.Flags
import com.android.systemui.Flags.msdlFeedback
@@ -51,11 +49,9 @@ import com.android.systemui.common.ui.view.onLayoutChanged
import com.android.systemui.common.ui.view.onTouchListener
import com.android.systemui.customization.R as customR
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.domain.interactor.WallpaperFocalAreaInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.ui.view.layout.sections.AodPromotedNotificationSection
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel
@@ -110,11 +106,9 @@ object KeyguardRootViewBinder {
        clockInteractor: KeyguardClockInteractor,
        wallpaperFocalAreaInteractor: WallpaperFocalAreaInteractor,
        clockViewModel: KeyguardClockViewModel,
        interactionJankMonitor: InteractionJankMonitor?,
        deviceEntryHapticsInteractor: DeviceEntryHapticsInteractor?,
        vibratorHelper: VibratorHelper?,
        falsingManager: FalsingManager?,
        keyguardViewMediator: KeyguardViewMediator?,
        statusBarKeyguardViewManager: StatusBarKeyguardViewManager?,
        mainImmediateDispatcher: CoroutineDispatcher,
        msdlPlayer: MSDLPlayer?,
@@ -308,35 +302,6 @@ object KeyguardRootViewBinder {
                        }
                    }

                    interactionJankMonitor?.let { jankMonitor ->
                        launch {
                            viewModel.goneToAodTransition.collect {
                                when (it.transitionState) {
                                    TransitionState.STARTED -> {
                                        val clockId = clockInteractor.renderedClockId
                                        val builder =
                                            InteractionJankMonitor.Configuration.Builder.withView(
                                                    CUJ_SCREEN_OFF_SHOW_AOD,
                                                    view,
                                                )
                                                .setTag(clockId)
                                        jankMonitor.begin(builder)
                                    }

                                    TransitionState.CANCELED ->
                                        jankMonitor.cancel(CUJ_SCREEN_OFF_SHOW_AOD)

                                    TransitionState.FINISHED -> {
                                        keyguardViewMediator?.maybeHandlePendingLock()
                                        jankMonitor.end(CUJ_SCREEN_OFF_SHOW_AOD)
                                    }

                                    TransitionState.RUNNING -> Unit
                                }
                            }
                        }
                    }

                    launch {
                        shadeInteractor.isAnyFullyExpanded.collect { isFullyAnyExpanded ->
                            view.visibility =
Loading