Loading packages/SystemUI/multivalentTests/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorTest.kt +0 −13 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat Loading @@ -36,18 +35,6 @@ class WindowRootViewBlurInteractorTest : SysuiTestCase() { val underTest by lazy { kosmos.windowRootViewBlurInteractor } @Test fun bouncerBlurIsAppliedImmediately() = testScope.runTest { val blurRadius by collectLastValue(underTest.blurRadius) val isBlurOpaque by collectLastValue(underTest.isBlurOpaque) underTest.requestBlurForBouncer(10) assertThat(blurRadius).isEqualTo(10) assertThat(isBlurOpaque).isFalse() } @Test fun shadeBlurIsNotAppliedWhenBouncerBlurIsActive() = testScope.runTest { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt +4 −2 Original line number Diff line number Diff line Loading @@ -46,12 +46,14 @@ class WindowRootViewModelTest : SysuiTestCase() { @Test fun bouncerTransitionChangesWindowBlurRadius() = testScope.runTest { val blurState by collectLastValue(underTest.blurState) val blurRadius by collectLastValue(underTest.blurRadius) val isBlurOpaque by collectLastValue(underTest.isBlurOpaque) runCurrent() kosmos.fakeBouncerTransitions.first().windowBlurRadius.value = 30.0f runCurrent() assertThat(blurState).isEqualTo(BlurState(radius = 30, isOpaque = false)) assertThat(blurRadius).isEqualTo(30) assertThat(isBlurOpaque).isEqualTo(false) } } packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt +28 −28 Original line number Diff line number Diff line Loading @@ -32,7 +32,9 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn Loading Loading @@ -72,37 +74,27 @@ constructor( /** Radius of blur to be applied on the window root view. */ val blurRadius: StateFlow<Int> = repository.blurRadius.asStateFlow() /** Whether the blur applied is opaque or transparent. */ val isBlurOpaque: StateFlow<Boolean> = repository.isBlurOpaque.asStateFlow() /** * Emits the applied blur radius whenever blur is successfully applied to the window root view. */ val onBlurAppliedEvent: Flow<Int> = repository.onBlurApplied /** * Request to apply blur while on bouncer, this takes precedence over other blurs (from shade). */ fun requestBlurForBouncer(blurRadius: Int) { repository.isBlurOpaque.value = false repository.blurRadius.value = blurRadius } /** * Request to apply blur while on glanceable hub, this takes precedence over other blurs (from * shade) except for bouncer. */ fun requestBlurForGlanceableHub(blurRadius: Int): Boolean { if (keyguardInteractor.primaryBouncerShowing.value) { return false } Log.d(TAG, "requestBlurForGlanceableHub for $blurRadius") repository.isBlurOpaque.value = false repository.blurRadius.value = blurRadius return true /** Whether the blur applied is opaque or transparent. */ val isBlurOpaque: Flow<Boolean> = combine( if (Flags.bouncerUiRevamp()) { keyguardInteractor.primaryBouncerShowing.or(isBouncerTransitionInProgress) } else { flowOf(false) }, if (Flags.glanceableHubBlurredBackground()) { communalInteractor.isCommunalBlurring } else { flowOf(false) }, repository.isBlurOpaque, ) { bouncerActive, ghActive, shadeBlurOpaque -> if (bouncerActive || ghActive) false else shadeBlurOpaque } /** Loading @@ -119,10 +111,10 @@ constructor( // We need to check either of these because they are two different sources of truth, // primaryBouncerShowing changes early to true/false, but blur is // coordinated by transition value. if (keyguardInteractor.primaryBouncerShowing.value || isBouncerTransitionInProgress.value) { if (isBouncerTransitionInProgress()) { return false } if (communalInteractor.isCommunalBlurring.value) { if (isGlanceableHubActive()) { return false } Log.d(TAG, "requestingBlurForShade for $blurRadius $opaque") Loading @@ -131,6 +123,14 @@ constructor( return true } private fun isGlanceableHubActive() = communalInteractor.isCommunalBlurring.value private fun isBouncerTransitionInProgress() = keyguardInteractor.primaryBouncerShowing.value || isBouncerTransitionInProgress.value private fun Flow<Boolean>.or(anotherFlow: Flow<Boolean>): Flow<Boolean> = this.combine(anotherFlow) { a, b -> a || b } companion object { const val TAG = "WindowRootViewBlurInteractor" } Loading packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt +39 −25 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.util.Log import android.view.Choreographer import android.view.Choreographer.FrameCallback import com.android.app.tracing.coroutines.TrackTracer import com.android.app.tracing.coroutines.launchTraced import com.android.systemui.Flags import com.android.systemui.lifecycle.WindowLifecycleState import com.android.systemui.lifecycle.repeatWhenAttached Loading @@ -29,8 +30,8 @@ import com.android.systemui.statusbar.BlurUtils import com.android.systemui.window.ui.viewmodel.WindowRootViewModel import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch /** * View binder that wires up window level UI transformations like blur to the [WindowRootView] Loading @@ -51,7 +52,6 @@ object WindowRootViewBinder { view.repeatWhenAttached(mainDispatcher) { Log.d(TAG, "Binding root view") var frameCallbackPendingExecution: FrameCallback? = null view.viewModel( minWindowLifecycleState = WindowLifecycleState.ATTACHED, factory = { viewModelFactory.create() }, Loading @@ -59,34 +59,48 @@ object WindowRootViewBinder { ) { viewModel -> try { Log.d(TAG, "Launching coroutines that update window root view state") launch { viewModel.blurState .filter { it.radius >= 0 } .collect { blurState -> launchTraced("WindowBlur") { var wasUpdateScheduledForThisFrame = false var lastScheduledBlurRadius = 0 var lastScheduleBlurOpaqueness = false // Creating the callback once and not for every coroutine invocation val newFrameCallback = FrameCallback { frameCallbackPendingExecution = null wasUpdateScheduledForThisFrame = false val blurRadiusToApply = lastScheduledBlurRadius blurUtils.applyBlur( view.rootView?.viewRootImpl, blurState.radius, blurState.isOpaque, blurRadiusToApply, lastScheduleBlurOpaqueness, ) TrackTracer.instantForGroup( "windowBlur", "appliedBlurRadius", blurState.radius, blurRadiusToApply, ) viewModel.onBlurApplied(blurState.radius) viewModel.onBlurApplied(blurRadiusToApply) } combine(viewModel.blurRadius, viewModel.isBlurOpaque, ::Pair) .filter { it.first >= 0 } .collect { (blurRadius, isOpaque) -> // Expectation is that we schedule only one blur radius value // per frame if (wasUpdateScheduledForThisFrame) { return@collect } TrackTracer.instantForGroup( "windowBlur", "preparedBlurRadius", blurState.radius, blurRadius, ) lastScheduledBlurRadius = blurRadius.toInt() lastScheduleBlurOpaqueness = isOpaque wasUpdateScheduledForThisFrame = true blurUtils.prepareBlur( view.rootView?.viewRootImpl, lastScheduledBlurRadius, ) blurUtils.prepareBlur(view.rootView?.viewRootImpl, blurState.radius) if (frameCallbackPendingExecution != null) { choreographer.removeFrameCallback(frameCallbackPendingExecution) } frameCallbackPendingExecution = newFrameCallback choreographer.postFrameCallback(newFrameCallback) } } Loading packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt +32 −52 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.systemui.window.ui.viewmodel import android.os.Build import android.util.Log import com.android.app.tracing.coroutines.launchTraced import com.android.systemui.Flags.glanceableHubBlurredBackground import com.android.systemui.Flags import com.android.systemui.keyguard.ui.transitions.GlanceableHubTransition import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition import com.android.systemui.lifecycle.ExclusiveActivatable Loading @@ -29,9 +29,9 @@ import dagger.assisted.AssistedInject import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach Loading @@ -41,14 +41,33 @@ typealias BlurAppliedUiEvent = Int class WindowRootViewModel @AssistedInject constructor( private val primaryBouncerTransitions: Set<@JvmSuppressWildcards PrimaryBouncerTransition>, private val glanceableHubTransitions: Set<@JvmSuppressWildcards GlanceableHubTransition>, primaryBouncerTransitions: Set<@JvmSuppressWildcards PrimaryBouncerTransition>, glanceableHubTransitions: Set<@JvmSuppressWildcards GlanceableHubTransition>, private val blurInteractor: WindowRootViewBlurInteractor, ) : ExclusiveActivatable() { private val blurEvents = Channel<BlurAppliedUiEvent>(Channel.BUFFERED) private val _blurState = MutableStateFlow(BlurState(0, false)) val blurState = _blurState.asStateFlow() private val bouncerBlurRadiusFlows = if (Flags.bouncerUiRevamp()) primaryBouncerTransitions.map { it.windowBlurRadius.logIfPossible(it.javaClass.name) } else emptyList() private val glanceableHubBlurRadiusFlows = if (Flags.glanceableHubBlurredBackground()) glanceableHubTransitions.map { it.windowBlurRadius.logIfPossible(it.javaClass.name) } else emptyList() val blurRadius: Flow<Float> = listOf( *bouncerBlurRadiusFlows.toTypedArray(), *glanceableHubBlurRadiusFlows.toTypedArray(), blurInteractor.blurRadius.map { it.toFloat() }.logIfPossible("ShadeBlur"), ) .merge() val isBlurOpaque = blurInteractor.isBlurOpaque.distinctUntilChanged().logIfPossible("isBlurOpaque") override suspend fun onActivated(): Nothing { coroutineScope { Loading @@ -60,49 +79,6 @@ constructor( blurInteractor.onBlurApplied(event) } } launchTraced("WindowRootViewModel#blurState") { combine(blurInteractor.blurRadius, blurInteractor.isBlurOpaque, ::BlurState) .collect { _blurState.value = it } } launchTraced("WindowRootViewModel#bouncerTransitions") { primaryBouncerTransitions .map { transition -> transition.windowBlurRadius.onEach { blurRadius -> if (isLoggable) { Log.d( TAG, "${transition.javaClass.simpleName} windowBlurRadius $blurRadius", ) } } } .merge() .collect { blurRadius -> blurInteractor.requestBlurForBouncer(blurRadius.toInt()) } } if (glanceableHubBlurredBackground()) { launchTraced("WindowRootViewModel#glanceableHubTransitions") { glanceableHubTransitions .map { transition -> transition.windowBlurRadius.onEach { blurRadius -> if (isLoggable) { Log.d( TAG, "${transition.javaClass.simpleName} windowBlurRadius $blurRadius", ) } } } .merge() .collect { blurRadius -> blurInteractor.requestBlurForGlanceableHub(blurRadius.toInt()) } } } } awaitCancellation() } Loading @@ -118,7 +94,11 @@ constructor( private companion object { const val TAG = "WindowRootViewModel" val isLoggable = Log.isLoggable(TAG, Log.DEBUG) || Build.isDebuggable() val isLoggable = Log.isLoggable(TAG, Log.VERBOSE) || Build.isDebuggable() fun <T> Flow<T>.logIfPossible(loggingInfo: String): Flow<T> { return onEach { if (isLoggable) Log.v(TAG, "$loggingInfo $it") } } } } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorTest.kt +0 −13 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat Loading @@ -36,18 +35,6 @@ class WindowRootViewBlurInteractorTest : SysuiTestCase() { val underTest by lazy { kosmos.windowRootViewBlurInteractor } @Test fun bouncerBlurIsAppliedImmediately() = testScope.runTest { val blurRadius by collectLastValue(underTest.blurRadius) val isBlurOpaque by collectLastValue(underTest.isBlurOpaque) underTest.requestBlurForBouncer(10) assertThat(blurRadius).isEqualTo(10) assertThat(isBlurOpaque).isFalse() } @Test fun shadeBlurIsNotAppliedWhenBouncerBlurIsActive() = testScope.runTest { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt +4 −2 Original line number Diff line number Diff line Loading @@ -46,12 +46,14 @@ class WindowRootViewModelTest : SysuiTestCase() { @Test fun bouncerTransitionChangesWindowBlurRadius() = testScope.runTest { val blurState by collectLastValue(underTest.blurState) val blurRadius by collectLastValue(underTest.blurRadius) val isBlurOpaque by collectLastValue(underTest.isBlurOpaque) runCurrent() kosmos.fakeBouncerTransitions.first().windowBlurRadius.value = 30.0f runCurrent() assertThat(blurState).isEqualTo(BlurState(radius = 30, isOpaque = false)) assertThat(blurRadius).isEqualTo(30) assertThat(isBlurOpaque).isEqualTo(false) } }
packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt +28 −28 Original line number Diff line number Diff line Loading @@ -32,7 +32,9 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn Loading Loading @@ -72,37 +74,27 @@ constructor( /** Radius of blur to be applied on the window root view. */ val blurRadius: StateFlow<Int> = repository.blurRadius.asStateFlow() /** Whether the blur applied is opaque or transparent. */ val isBlurOpaque: StateFlow<Boolean> = repository.isBlurOpaque.asStateFlow() /** * Emits the applied blur radius whenever blur is successfully applied to the window root view. */ val onBlurAppliedEvent: Flow<Int> = repository.onBlurApplied /** * Request to apply blur while on bouncer, this takes precedence over other blurs (from shade). */ fun requestBlurForBouncer(blurRadius: Int) { repository.isBlurOpaque.value = false repository.blurRadius.value = blurRadius } /** * Request to apply blur while on glanceable hub, this takes precedence over other blurs (from * shade) except for bouncer. */ fun requestBlurForGlanceableHub(blurRadius: Int): Boolean { if (keyguardInteractor.primaryBouncerShowing.value) { return false } Log.d(TAG, "requestBlurForGlanceableHub for $blurRadius") repository.isBlurOpaque.value = false repository.blurRadius.value = blurRadius return true /** Whether the blur applied is opaque or transparent. */ val isBlurOpaque: Flow<Boolean> = combine( if (Flags.bouncerUiRevamp()) { keyguardInteractor.primaryBouncerShowing.or(isBouncerTransitionInProgress) } else { flowOf(false) }, if (Flags.glanceableHubBlurredBackground()) { communalInteractor.isCommunalBlurring } else { flowOf(false) }, repository.isBlurOpaque, ) { bouncerActive, ghActive, shadeBlurOpaque -> if (bouncerActive || ghActive) false else shadeBlurOpaque } /** Loading @@ -119,10 +111,10 @@ constructor( // We need to check either of these because they are two different sources of truth, // primaryBouncerShowing changes early to true/false, but blur is // coordinated by transition value. if (keyguardInteractor.primaryBouncerShowing.value || isBouncerTransitionInProgress.value) { if (isBouncerTransitionInProgress()) { return false } if (communalInteractor.isCommunalBlurring.value) { if (isGlanceableHubActive()) { return false } Log.d(TAG, "requestingBlurForShade for $blurRadius $opaque") Loading @@ -131,6 +123,14 @@ constructor( return true } private fun isGlanceableHubActive() = communalInteractor.isCommunalBlurring.value private fun isBouncerTransitionInProgress() = keyguardInteractor.primaryBouncerShowing.value || isBouncerTransitionInProgress.value private fun Flow<Boolean>.or(anotherFlow: Flow<Boolean>): Flow<Boolean> = this.combine(anotherFlow) { a, b -> a || b } companion object { const val TAG = "WindowRootViewBlurInteractor" } Loading
packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt +39 −25 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.util.Log import android.view.Choreographer import android.view.Choreographer.FrameCallback import com.android.app.tracing.coroutines.TrackTracer import com.android.app.tracing.coroutines.launchTraced import com.android.systemui.Flags import com.android.systemui.lifecycle.WindowLifecycleState import com.android.systemui.lifecycle.repeatWhenAttached Loading @@ -29,8 +30,8 @@ import com.android.systemui.statusbar.BlurUtils import com.android.systemui.window.ui.viewmodel.WindowRootViewModel import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch /** * View binder that wires up window level UI transformations like blur to the [WindowRootView] Loading @@ -51,7 +52,6 @@ object WindowRootViewBinder { view.repeatWhenAttached(mainDispatcher) { Log.d(TAG, "Binding root view") var frameCallbackPendingExecution: FrameCallback? = null view.viewModel( minWindowLifecycleState = WindowLifecycleState.ATTACHED, factory = { viewModelFactory.create() }, Loading @@ -59,34 +59,48 @@ object WindowRootViewBinder { ) { viewModel -> try { Log.d(TAG, "Launching coroutines that update window root view state") launch { viewModel.blurState .filter { it.radius >= 0 } .collect { blurState -> launchTraced("WindowBlur") { var wasUpdateScheduledForThisFrame = false var lastScheduledBlurRadius = 0 var lastScheduleBlurOpaqueness = false // Creating the callback once and not for every coroutine invocation val newFrameCallback = FrameCallback { frameCallbackPendingExecution = null wasUpdateScheduledForThisFrame = false val blurRadiusToApply = lastScheduledBlurRadius blurUtils.applyBlur( view.rootView?.viewRootImpl, blurState.radius, blurState.isOpaque, blurRadiusToApply, lastScheduleBlurOpaqueness, ) TrackTracer.instantForGroup( "windowBlur", "appliedBlurRadius", blurState.radius, blurRadiusToApply, ) viewModel.onBlurApplied(blurState.radius) viewModel.onBlurApplied(blurRadiusToApply) } combine(viewModel.blurRadius, viewModel.isBlurOpaque, ::Pair) .filter { it.first >= 0 } .collect { (blurRadius, isOpaque) -> // Expectation is that we schedule only one blur radius value // per frame if (wasUpdateScheduledForThisFrame) { return@collect } TrackTracer.instantForGroup( "windowBlur", "preparedBlurRadius", blurState.radius, blurRadius, ) lastScheduledBlurRadius = blurRadius.toInt() lastScheduleBlurOpaqueness = isOpaque wasUpdateScheduledForThisFrame = true blurUtils.prepareBlur( view.rootView?.viewRootImpl, lastScheduledBlurRadius, ) blurUtils.prepareBlur(view.rootView?.viewRootImpl, blurState.radius) if (frameCallbackPendingExecution != null) { choreographer.removeFrameCallback(frameCallbackPendingExecution) } frameCallbackPendingExecution = newFrameCallback choreographer.postFrameCallback(newFrameCallback) } } Loading
packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt +32 −52 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.systemui.window.ui.viewmodel import android.os.Build import android.util.Log import com.android.app.tracing.coroutines.launchTraced import com.android.systemui.Flags.glanceableHubBlurredBackground import com.android.systemui.Flags import com.android.systemui.keyguard.ui.transitions.GlanceableHubTransition import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition import com.android.systemui.lifecycle.ExclusiveActivatable Loading @@ -29,9 +29,9 @@ import dagger.assisted.AssistedInject import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach Loading @@ -41,14 +41,33 @@ typealias BlurAppliedUiEvent = Int class WindowRootViewModel @AssistedInject constructor( private val primaryBouncerTransitions: Set<@JvmSuppressWildcards PrimaryBouncerTransition>, private val glanceableHubTransitions: Set<@JvmSuppressWildcards GlanceableHubTransition>, primaryBouncerTransitions: Set<@JvmSuppressWildcards PrimaryBouncerTransition>, glanceableHubTransitions: Set<@JvmSuppressWildcards GlanceableHubTransition>, private val blurInteractor: WindowRootViewBlurInteractor, ) : ExclusiveActivatable() { private val blurEvents = Channel<BlurAppliedUiEvent>(Channel.BUFFERED) private val _blurState = MutableStateFlow(BlurState(0, false)) val blurState = _blurState.asStateFlow() private val bouncerBlurRadiusFlows = if (Flags.bouncerUiRevamp()) primaryBouncerTransitions.map { it.windowBlurRadius.logIfPossible(it.javaClass.name) } else emptyList() private val glanceableHubBlurRadiusFlows = if (Flags.glanceableHubBlurredBackground()) glanceableHubTransitions.map { it.windowBlurRadius.logIfPossible(it.javaClass.name) } else emptyList() val blurRadius: Flow<Float> = listOf( *bouncerBlurRadiusFlows.toTypedArray(), *glanceableHubBlurRadiusFlows.toTypedArray(), blurInteractor.blurRadius.map { it.toFloat() }.logIfPossible("ShadeBlur"), ) .merge() val isBlurOpaque = blurInteractor.isBlurOpaque.distinctUntilChanged().logIfPossible("isBlurOpaque") override suspend fun onActivated(): Nothing { coroutineScope { Loading @@ -60,49 +79,6 @@ constructor( blurInteractor.onBlurApplied(event) } } launchTraced("WindowRootViewModel#blurState") { combine(blurInteractor.blurRadius, blurInteractor.isBlurOpaque, ::BlurState) .collect { _blurState.value = it } } launchTraced("WindowRootViewModel#bouncerTransitions") { primaryBouncerTransitions .map { transition -> transition.windowBlurRadius.onEach { blurRadius -> if (isLoggable) { Log.d( TAG, "${transition.javaClass.simpleName} windowBlurRadius $blurRadius", ) } } } .merge() .collect { blurRadius -> blurInteractor.requestBlurForBouncer(blurRadius.toInt()) } } if (glanceableHubBlurredBackground()) { launchTraced("WindowRootViewModel#glanceableHubTransitions") { glanceableHubTransitions .map { transition -> transition.windowBlurRadius.onEach { blurRadius -> if (isLoggable) { Log.d( TAG, "${transition.javaClass.simpleName} windowBlurRadius $blurRadius", ) } } } .merge() .collect { blurRadius -> blurInteractor.requestBlurForGlanceableHub(blurRadius.toInt()) } } } } awaitCancellation() } Loading @@ -118,7 +94,11 @@ constructor( private companion object { const val TAG = "WindowRootViewModel" val isLoggable = Log.isLoggable(TAG, Log.DEBUG) || Build.isDebuggable() val isLoggable = Log.isLoggable(TAG, Log.VERBOSE) || Build.isDebuggable() fun <T> Flow<T>.logIfPossible(loggingInfo: String): Flow<T> { return onEach { if (isLoggable) Log.v(TAG, "$loggingInfo $it") } } } } Loading