Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java +2 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.res.R; import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInteractorKosmosKt; import com.android.systemui.screencapture.record.domain.interactor.ScreenCaptureRecordFeaturesInteractorKosmosKt; import com.android.systemui.screenrecord.ScreenRecordUxController; import com.android.systemui.settings.UserContextProvider; Loading Loading @@ -161,6 +162,7 @@ public class ScreenRecordTileTest extends SysuiTestCase { mMediaProjectionMetricsLogger, ScreenCaptureRecordFeaturesInteractorKosmosKt .getScreenCaptureRecordFeaturesInteractor(mKosmos), ScreenCaptureUiInteractorKosmosKt.getScreenCaptureUiInteractor(mKosmos), mUserContextProvider ); Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt +3 −4 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.systemui.plugins.activityStarter import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.res.R import com.android.systemui.screencapture.domain.interactor.screenCaptureUiInteractor import com.android.systemui.screenrecord.ScreenRecordUxController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepositoryImpl Loading Loading @@ -73,7 +74,6 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { private val underTest by lazy { ScreenRecordTileUserActionInteractor( context, testScope.testScheduler, testScope.testScheduler, screenRecordRepository, Loading @@ -83,6 +83,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { keyguardDismissUtil, dialogTransitionAnimator, panelInteractor, kosmos.screenCaptureUiInteractor, mock<MediaProjectionMetricsLogger>(), ) } Loading @@ -101,9 +102,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { @EnableFlags(Flags.FLAG_LARGE_SCREEN_SCREENCAPTURE, Flags.FLAG_NEW_SCREEN_RECORD_TOOLBAR) fun handleClick_fromLargeScreen_flagEnabled_isNOP() = runTest { val recordingModel = ScreenRecordModel.DoingNothing // Override the resource to enable large screen features. underTest.apply { overrideResource(R.bool.config_enableLargeScreenScreencapture, true) } overrideResource(R.bool.config_enableLargeScreenScreencapture, true) underTest.handleInput(QSTileInputTestKtx.click(recordingModel)) verify(screenRecordUxController, never()).createScreenRecordDialog(any()) Loading packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +14 −9 Original line number Diff line number Diff line Loading @@ -52,8 +52,8 @@ import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.res.R; import com.android.systemui.screencapture.common.shared.model.ScreenCaptureActivityIntentParameters; import com.android.systemui.screencapture.common.shared.model.ScreenCaptureType; import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInteractor; import com.android.systemui.screencapture.record.domain.interactor.ScreenCaptureRecordFeaturesInteractor; import com.android.systemui.screencapture.ui.ScreenCaptureActivity; import com.android.systemui.screenrecord.ScreenRecordUxController; import com.android.systemui.screenrecord.data.model.ScreenRecordModel; import com.android.systemui.settings.UserContextProvider; Loading Loading @@ -82,6 +82,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> private final PanelInteractor mPanelInteractor; private final MediaProjectionMetricsLogger mMediaProjectionMetricsLogger; private final UserContextProvider mUserContextProvider; private final ScreenCaptureUiInteractor mScreenCaptureUiInteractor; private final ScreenCaptureRecordFeaturesInteractor mScreenCaptureRecordFeaturesInteractor; private long mMillisUntilFinished = 0; Loading @@ -105,6 +106,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> PanelInteractor panelInteractor, MediaProjectionMetricsLogger mediaProjectionMetricsLogger, ScreenCaptureRecordFeaturesInteractor screenCaptureRecordFeaturesInteractor, ScreenCaptureUiInteractor screenCaptureUiInteractor, UserContextProvider userContextProvider ) { super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger, Loading @@ -118,6 +120,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> mPanelInteractor = panelInteractor; mMediaProjectionMetricsLogger = mediaProjectionMetricsLogger; mScreenCaptureRecordFeaturesInteractor = screenCaptureRecordFeaturesInteractor; mScreenCaptureUiInteractor = screenCaptureUiInteractor; mUserContextProvider = userContextProvider; } Loading @@ -133,15 +136,17 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> protected void handleClick(@Nullable Expandable expandable) { if (ScreenCaptureRecordFeaturesInteractor.Companion.getShouldShowNewToolbar()) { UserHandle userHandle = UserHandle.of(getCurrentTileUser()); final Intent intent = new Intent(mContext, ScreenCaptureActivity.class); // TODO(b/412723197): pass actual params here. new ScreenCaptureActivityIntentParameters(ScreenCaptureType.RECORD, false, null, null, userHandle, 0 ).fillIntent(intent); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); mActivityStarter.postQSRunnableDismissingKeyguard( () -> mActivityStarter.startActivity(intent, true)); () -> mScreenCaptureUiInteractor.show( new ScreenCaptureActivityIntentParameters( /* screenCaptureType= */ ScreenCaptureType.RECORD, /* isUserConsentRequired= */ false, /* resultReceiver= */ null, /* mediaProjection= */ null, /* hostAppUserHandle= */ userHandle, /* hostAppUid= */ 0 ) )); } else { // TODO(b/409330121): call mController.onScreenRecordQsTileClick() instead. handleClick(() -> showDialog(expandable)); Loading packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt +12 −17 Original line number Diff line number Diff line Loading @@ -16,15 +16,12 @@ package com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor import android.content.Context import android.content.Intent import android.media.projection.StopReason import android.util.Log import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.animation.Expandable import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor Loading @@ -36,8 +33,8 @@ import com.android.systemui.qs.tiles.base.domain.model.QSTileInput import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.screencapture.common.shared.model.ScreenCaptureActivityIntentParameters import com.android.systemui.screencapture.common.shared.model.ScreenCaptureType import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInteractor import com.android.systemui.screencapture.record.domain.interactor.ScreenCaptureRecordFeaturesInteractor import com.android.systemui.screencapture.ui.ScreenCaptureActivity import com.android.systemui.screenrecord.ScreenRecordUxController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository Loading @@ -50,7 +47,6 @@ import kotlinx.coroutines.withContext class ScreenRecordTileUserActionInteractor @Inject constructor( @Application private val context: Context, @Main private val mainContext: CoroutineContext, @Background private val backgroundContext: CoroutineContext, private val screenRecordRepository: ScreenRecordRepository, Loading @@ -60,6 +56,7 @@ constructor( private val keyguardDismissUtil: KeyguardDismissUtil, private val dialogTransitionAnimator: DialogTransitionAnimator, private val panelInteractor: PanelInteractor, private val screenCaptureUiInteractor: ScreenCaptureUiInteractor, private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, ) : QSTileUserActionInteractor<ScreenRecordModel> { override suspend fun handleInput(input: QSTileInput<ScreenRecordModel>): Unit = Loading @@ -67,9 +64,9 @@ constructor( when (action) { is QSTileUserAction.Click -> { if (ScreenCaptureRecordFeaturesInteractor.shouldShowNewToolbar) { val intent = Intent(context, ScreenCaptureActivity::class.java) // TODO(b/412723197): pass actual params here. activityStarter.postQSRunnableDismissingKeyguard { screenCaptureUiInteractor.show( ScreenCaptureActivityIntentParameters( ScreenCaptureType.RECORD, isUserConsentRequired = false, Loading @@ -78,9 +75,7 @@ constructor( hostAppUserHandle = user, hostAppUid = 0, ) .fillIntent(intent) activityStarter.postQSRunnableDismissingKeyguard { activityStarter.startActivity(intent, true) ) } } else { when (data) { Loading packages/SystemUI/src/com/android/systemui/screencapture/ScreenCaptureUiStartable.kt 0 → 100644 +69 −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.screencapture import android.util.Log import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.display.data.repository.DisplayRepository import com.android.systemui.display.data.repository.FocusedDisplayRepository import com.android.systemui.screencapture.common.shared.model.ScreenCaptureType import com.android.systemui.screencapture.common.shared.model.ScreenCaptureUiState import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInteractor import com.android.systemui.screencapture.ui.ScreenCaptureUi import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @SysUISingleton class ScreenCaptureUiStartable @Inject constructor( @Application private val appScope: CoroutineScope, private val screenCaptureUiInteractor: ScreenCaptureUiInteractor, private val screenCaptureUiFactory: ScreenCaptureUi.Factory, private val focusedDisplayRepository: FocusedDisplayRepository, private val displayRepository: DisplayRepository, ) : CoreStartable { override fun start() { ScreenCaptureType.entries.forEach { observeUiState(it) } } private fun observeUiState(type: ScreenCaptureType) { screenCaptureUiInteractor .uiState(type) .onEach { state -> if (state is ScreenCaptureUiState.Visible) { val displayId = focusedDisplayRepository.focusedDisplayId.value val display = displayRepository.getDisplay(displayId) if (display == null) { Log.e("ScreenCapture", "Couldn't find display for id=$displayId") screenCaptureUiInteractor.hide(type) } else { screenCaptureUiFactory .create(type = state.parameters.screenCaptureType, display = display) .attachWindow() } } } .launchIn(appScope) } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java +2 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.res.R; import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInteractorKosmosKt; import com.android.systemui.screencapture.record.domain.interactor.ScreenCaptureRecordFeaturesInteractorKosmosKt; import com.android.systemui.screenrecord.ScreenRecordUxController; import com.android.systemui.settings.UserContextProvider; Loading Loading @@ -161,6 +162,7 @@ public class ScreenRecordTileTest extends SysuiTestCase { mMediaProjectionMetricsLogger, ScreenCaptureRecordFeaturesInteractorKosmosKt .getScreenCaptureRecordFeaturesInteractor(mKosmos), ScreenCaptureUiInteractorKosmosKt.getScreenCaptureUiInteractor(mKosmos), mUserContextProvider ); Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt +3 −4 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.systemui.plugins.activityStarter import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx import com.android.systemui.res.R import com.android.systemui.screencapture.domain.interactor.screenCaptureUiInteractor import com.android.systemui.screenrecord.ScreenRecordUxController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepositoryImpl Loading Loading @@ -73,7 +74,6 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { private val underTest by lazy { ScreenRecordTileUserActionInteractor( context, testScope.testScheduler, testScope.testScheduler, screenRecordRepository, Loading @@ -83,6 +83,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { keyguardDismissUtil, dialogTransitionAnimator, panelInteractor, kosmos.screenCaptureUiInteractor, mock<MediaProjectionMetricsLogger>(), ) } Loading @@ -101,9 +102,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { @EnableFlags(Flags.FLAG_LARGE_SCREEN_SCREENCAPTURE, Flags.FLAG_NEW_SCREEN_RECORD_TOOLBAR) fun handleClick_fromLargeScreen_flagEnabled_isNOP() = runTest { val recordingModel = ScreenRecordModel.DoingNothing // Override the resource to enable large screen features. underTest.apply { overrideResource(R.bool.config_enableLargeScreenScreencapture, true) } overrideResource(R.bool.config_enableLargeScreenScreencapture, true) underTest.handleInput(QSTileInputTestKtx.click(recordingModel)) verify(screenRecordUxController, never()).createScreenRecordDialog(any()) Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +14 −9 Original line number Diff line number Diff line Loading @@ -52,8 +52,8 @@ import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.res.R; import com.android.systemui.screencapture.common.shared.model.ScreenCaptureActivityIntentParameters; import com.android.systemui.screencapture.common.shared.model.ScreenCaptureType; import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInteractor; import com.android.systemui.screencapture.record.domain.interactor.ScreenCaptureRecordFeaturesInteractor; import com.android.systemui.screencapture.ui.ScreenCaptureActivity; import com.android.systemui.screenrecord.ScreenRecordUxController; import com.android.systemui.screenrecord.data.model.ScreenRecordModel; import com.android.systemui.settings.UserContextProvider; Loading Loading @@ -82,6 +82,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> private final PanelInteractor mPanelInteractor; private final MediaProjectionMetricsLogger mMediaProjectionMetricsLogger; private final UserContextProvider mUserContextProvider; private final ScreenCaptureUiInteractor mScreenCaptureUiInteractor; private final ScreenCaptureRecordFeaturesInteractor mScreenCaptureRecordFeaturesInteractor; private long mMillisUntilFinished = 0; Loading @@ -105,6 +106,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> PanelInteractor panelInteractor, MediaProjectionMetricsLogger mediaProjectionMetricsLogger, ScreenCaptureRecordFeaturesInteractor screenCaptureRecordFeaturesInteractor, ScreenCaptureUiInteractor screenCaptureUiInteractor, UserContextProvider userContextProvider ) { super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger, Loading @@ -118,6 +120,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> mPanelInteractor = panelInteractor; mMediaProjectionMetricsLogger = mediaProjectionMetricsLogger; mScreenCaptureRecordFeaturesInteractor = screenCaptureRecordFeaturesInteractor; mScreenCaptureUiInteractor = screenCaptureUiInteractor; mUserContextProvider = userContextProvider; } Loading @@ -133,15 +136,17 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> protected void handleClick(@Nullable Expandable expandable) { if (ScreenCaptureRecordFeaturesInteractor.Companion.getShouldShowNewToolbar()) { UserHandle userHandle = UserHandle.of(getCurrentTileUser()); final Intent intent = new Intent(mContext, ScreenCaptureActivity.class); // TODO(b/412723197): pass actual params here. new ScreenCaptureActivityIntentParameters(ScreenCaptureType.RECORD, false, null, null, userHandle, 0 ).fillIntent(intent); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); mActivityStarter.postQSRunnableDismissingKeyguard( () -> mActivityStarter.startActivity(intent, true)); () -> mScreenCaptureUiInteractor.show( new ScreenCaptureActivityIntentParameters( /* screenCaptureType= */ ScreenCaptureType.RECORD, /* isUserConsentRequired= */ false, /* resultReceiver= */ null, /* mediaProjection= */ null, /* hostAppUserHandle= */ userHandle, /* hostAppUid= */ 0 ) )); } else { // TODO(b/409330121): call mController.onScreenRecordQsTileClick() instead. handleClick(() -> showDialog(expandable)); Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt +12 −17 Original line number Diff line number Diff line Loading @@ -16,15 +16,12 @@ package com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor import android.content.Context import android.content.Intent import android.media.projection.StopReason import android.util.Log import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.animation.Expandable import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor Loading @@ -36,8 +33,8 @@ import com.android.systemui.qs.tiles.base.domain.model.QSTileInput import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction import com.android.systemui.screencapture.common.shared.model.ScreenCaptureActivityIntentParameters import com.android.systemui.screencapture.common.shared.model.ScreenCaptureType import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInteractor import com.android.systemui.screencapture.record.domain.interactor.ScreenCaptureRecordFeaturesInteractor import com.android.systemui.screencapture.ui.ScreenCaptureActivity import com.android.systemui.screenrecord.ScreenRecordUxController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository Loading @@ -50,7 +47,6 @@ import kotlinx.coroutines.withContext class ScreenRecordTileUserActionInteractor @Inject constructor( @Application private val context: Context, @Main private val mainContext: CoroutineContext, @Background private val backgroundContext: CoroutineContext, private val screenRecordRepository: ScreenRecordRepository, Loading @@ -60,6 +56,7 @@ constructor( private val keyguardDismissUtil: KeyguardDismissUtil, private val dialogTransitionAnimator: DialogTransitionAnimator, private val panelInteractor: PanelInteractor, private val screenCaptureUiInteractor: ScreenCaptureUiInteractor, private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, ) : QSTileUserActionInteractor<ScreenRecordModel> { override suspend fun handleInput(input: QSTileInput<ScreenRecordModel>): Unit = Loading @@ -67,9 +64,9 @@ constructor( when (action) { is QSTileUserAction.Click -> { if (ScreenCaptureRecordFeaturesInteractor.shouldShowNewToolbar) { val intent = Intent(context, ScreenCaptureActivity::class.java) // TODO(b/412723197): pass actual params here. activityStarter.postQSRunnableDismissingKeyguard { screenCaptureUiInteractor.show( ScreenCaptureActivityIntentParameters( ScreenCaptureType.RECORD, isUserConsentRequired = false, Loading @@ -78,9 +75,7 @@ constructor( hostAppUserHandle = user, hostAppUid = 0, ) .fillIntent(intent) activityStarter.postQSRunnableDismissingKeyguard { activityStarter.startActivity(intent, true) ) } } else { when (data) { Loading
packages/SystemUI/src/com/android/systemui/screencapture/ScreenCaptureUiStartable.kt 0 → 100644 +69 −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.screencapture import android.util.Log import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.display.data.repository.DisplayRepository import com.android.systemui.display.data.repository.FocusedDisplayRepository import com.android.systemui.screencapture.common.shared.model.ScreenCaptureType import com.android.systemui.screencapture.common.shared.model.ScreenCaptureUiState import com.android.systemui.screencapture.domain.interactor.ScreenCaptureUiInteractor import com.android.systemui.screencapture.ui.ScreenCaptureUi import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @SysUISingleton class ScreenCaptureUiStartable @Inject constructor( @Application private val appScope: CoroutineScope, private val screenCaptureUiInteractor: ScreenCaptureUiInteractor, private val screenCaptureUiFactory: ScreenCaptureUi.Factory, private val focusedDisplayRepository: FocusedDisplayRepository, private val displayRepository: DisplayRepository, ) : CoreStartable { override fun start() { ScreenCaptureType.entries.forEach { observeUiState(it) } } private fun observeUiState(type: ScreenCaptureType) { screenCaptureUiInteractor .uiState(type) .onEach { state -> if (state is ScreenCaptureUiState.Visible) { val displayId = focusedDisplayRepository.focusedDisplayId.value val display = displayRepository.getDisplay(displayId) if (display == null) { Log.e("ScreenCapture", "Couldn't find display for id=$displayId") screenCaptureUiInteractor.hide(type) } else { screenCaptureUiFactory .create(type = state.parameters.screenCaptureType, display = display) .attachWindow() } } } .launchIn(appScope) } }