• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.keyguard.ui.binder
18 
19 import android.view.ViewGroup
20 import androidx.lifecycle.Lifecycle
21 import androidx.lifecycle.repeatOnLifecycle
22 import com.android.app.tracing.coroutines.launchTraced as launch
23 import com.android.internal.jank.Cuj.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD
24 import com.android.internal.jank.Cuj.CUJ_LOCKSCREEN_TRANSITION_TO_AOD
25 import com.android.internal.jank.Cuj.CUJ_SCREEN_OFF_SHOW_AOD
26 import com.android.internal.jank.InteractionJankMonitor
27 import com.android.systemui.keyguard.KeyguardViewMediator
28 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
29 import com.android.systemui.keyguard.shared.model.TransitionState
30 import com.android.systemui.keyguard.shared.model.TransitionStep
31 import com.android.systemui.keyguard.ui.viewmodel.KeyguardJankViewModel
32 import com.android.systemui.lifecycle.repeatWhenAttached
33 import com.android.systemui.scene.shared.flag.SceneContainerFlag
34 import kotlinx.coroutines.CoroutineDispatcher
35 import kotlinx.coroutines.DisposableHandle
36 import kotlinx.coroutines.ExperimentalCoroutinesApi
37 
38 /** Jank monitoring related to keyguard and transitions. */
39 @OptIn(ExperimentalCoroutinesApi::class)
40 object KeyguardJankBinder {
41     @JvmStatic
bindnull42     fun bind(
43         view: ViewGroup,
44         viewModel: KeyguardJankViewModel,
45         jankMonitor: InteractionJankMonitor?,
46         clockInteractor: KeyguardClockInteractor,
47         keyguardViewMediator: KeyguardViewMediator?,
48         mainImmediateDispatcher: CoroutineDispatcher,
49     ): DisposableHandle? {
50         if (jankMonitor == null) {
51             return null
52         }
53 
54         fun processStep(step: TransitionStep, cuj: Int) {
55             val clockId = clockInteractor.renderedClockId
56             when (step.transitionState) {
57                 TransitionState.STARTED -> {
58                     val builder =
59                         InteractionJankMonitor.Configuration.Builder.withView(cuj, view)
60                             .setTag(clockId)
61                     jankMonitor.begin(builder)
62                 }
63 
64                 TransitionState.CANCELED -> jankMonitor.cancel(cuj)
65 
66                 TransitionState.FINISHED -> jankMonitor.end(cuj)
67 
68                 TransitionState.RUNNING -> Unit
69             }
70         }
71 
72         return view.repeatWhenAttached(mainImmediateDispatcher) {
73             repeatOnLifecycle(Lifecycle.State.CREATED) {
74                 launch {
75                     viewModel.goneToAodTransition.collect {
76                         processStep(it, CUJ_SCREEN_OFF_SHOW_AOD)
77                         if (it.transitionState == TransitionState.FINISHED) {
78                             keyguardViewMediator?.maybeHandlePendingLock()
79                         }
80                     }
81                 }
82 
83                 // The following is already done in KeyguardTransitionAnimationCallbackImpl.
84                 if (!SceneContainerFlag.isEnabled) {
85                     launch {
86                         viewModel.lockscreenToAodTransition.collect {
87                             processStep(it, CUJ_LOCKSCREEN_TRANSITION_TO_AOD)
88                         }
89                     }
90 
91                     launch {
92                         viewModel.aodToLockscreenTransition.collect {
93                             processStep(it, CUJ_LOCKSCREEN_TRANSITION_FROM_AOD)
94                         }
95                     }
96                 }
97             }
98         }
99     }
100 }
101