Loading packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -1621,6 +1621,16 @@ flag { bug: "362719719" } flag { name: "transition_race_condition_part2" namespace: "systemui" description: "Thread-safe keyguard transitions" bug: "409585200" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "media_projection_request_attribution_fix" namespace: "systemui" Loading packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt +27 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.util.Log import com.android.app.animation.Interpolators import com.android.app.tracing.coroutines.flow.traceAs import com.android.app.tracing.coroutines.withContextTraced as withContext import com.android.systemui.Flags.transitionRaceConditionPart2 import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.shared.model.KeyguardState Loading Loading @@ -192,9 +193,14 @@ constructor( // Animators must be started on the main thread. return withContext("$TAG#startTransition", mainDispatcher) { if (!transitionRaceConditionPart2()) { withContextMutex.unlock() } if (lastStep.from == info.from && lastStep.to == info.to) { Log.i(TAG, "Duplicate call to start the transition, rejecting: $info") if (transitionRaceConditionPart2()) { withContextMutex.unlock() } return@withContext null } val isAnimatorRunning = lastAnimator?.isRunning() ?: false Loading Loading @@ -264,6 +270,9 @@ constructor( animator.addListener(animatorListener) animator.addUpdateListener(updateListener) animator.start() if (transitionRaceConditionPart2()) { withContextMutex.unlock() } return@withContext null } ?: run { Loading @@ -274,6 +283,9 @@ constructor( // No animator, so it's manual. Provide a mechanism to callback updateTransitionId = UUID.randomUUID() if (transitionRaceConditionPart2()) { withContextMutex.unlock() } return@withContext updateTransitionId } } Loading @@ -289,9 +301,15 @@ constructor( // requires the same lock withContextMutex.lock() withContext("$TAG#updateTransition", mainDispatcher) { if (!transitionRaceConditionPart2()) { withContextMutex.unlock() } updateTransitionInternal(transitionId, value, state) if (transitionRaceConditionPart2()) { withContextMutex.unlock() } } } Loading @@ -303,7 +321,9 @@ constructor( withContextMutex.lock() return withContext("$TAG#forceFinishCurrentTransition", mainDispatcher) { if (!transitionRaceConditionPart2()) { withContextMutex.unlock() } Log.d(TAG, "forceFinishCurrentTransition() - emitting FINISHED early.") Loading @@ -319,6 +339,10 @@ constructor( // Ask the listener to emit FINISHED and clean up its state. animatorListener?.onAnimationEnd(this) } if (transitionRaceConditionPart2()) { withContextMutex.unlock() } } } Loading Loading
packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -1621,6 +1621,16 @@ flag { bug: "362719719" } flag { name: "transition_race_condition_part2" namespace: "systemui" description: "Thread-safe keyguard transitions" bug: "409585200" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "media_projection_request_attribution_fix" namespace: "systemui" Loading
packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt +27 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.util.Log import com.android.app.animation.Interpolators import com.android.app.tracing.coroutines.flow.traceAs import com.android.app.tracing.coroutines.withContextTraced as withContext import com.android.systemui.Flags.transitionRaceConditionPart2 import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.shared.model.KeyguardState Loading Loading @@ -192,9 +193,14 @@ constructor( // Animators must be started on the main thread. return withContext("$TAG#startTransition", mainDispatcher) { if (!transitionRaceConditionPart2()) { withContextMutex.unlock() } if (lastStep.from == info.from && lastStep.to == info.to) { Log.i(TAG, "Duplicate call to start the transition, rejecting: $info") if (transitionRaceConditionPart2()) { withContextMutex.unlock() } return@withContext null } val isAnimatorRunning = lastAnimator?.isRunning() ?: false Loading Loading @@ -264,6 +270,9 @@ constructor( animator.addListener(animatorListener) animator.addUpdateListener(updateListener) animator.start() if (transitionRaceConditionPart2()) { withContextMutex.unlock() } return@withContext null } ?: run { Loading @@ -274,6 +283,9 @@ constructor( // No animator, so it's manual. Provide a mechanism to callback updateTransitionId = UUID.randomUUID() if (transitionRaceConditionPart2()) { withContextMutex.unlock() } return@withContext updateTransitionId } } Loading @@ -289,9 +301,15 @@ constructor( // requires the same lock withContextMutex.lock() withContext("$TAG#updateTransition", mainDispatcher) { if (!transitionRaceConditionPart2()) { withContextMutex.unlock() } updateTransitionInternal(transitionId, value, state) if (transitionRaceConditionPart2()) { withContextMutex.unlock() } } } Loading @@ -303,7 +321,9 @@ constructor( withContextMutex.lock() return withContext("$TAG#forceFinishCurrentTransition", mainDispatcher) { if (!transitionRaceConditionPart2()) { withContextMutex.unlock() } Log.d(TAG, "forceFinishCurrentTransition() - emitting FINISHED early.") Loading @@ -319,6 +339,10 @@ constructor( // Ask the listener to emit FINISHED and clean up its state. animatorListener?.onAnimationEnd(this) } if (transitionRaceConditionPart2()) { withContextMutex.unlock() } } } Loading