[PM-27092] Changing screen capture flow from event based to state based on Authenticator (#6062)

This commit is contained in:
aj-rosado 2025-10-24 10:26:53 +01:00 committed by GitHub
parent 38bdda0a41
commit be27c76bd3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 15 deletions

View File

@ -62,6 +62,7 @@ class MainActivity : AppCompatActivity() {
setupEdgeToEdge(appThemeFlow = mainViewModel.stateFlow.map { it.theme })
setContent {
val state by mainViewModel.stateFlow.collectAsStateWithLifecycle()
updateScreenCapture(isScreenCaptureAllowed = state.isScreenCaptureAllowed)
val navController = rememberNavController()
observeViewModelEvents(navController)
LocalManagerProvider {
@ -96,10 +97,6 @@ class MainActivity : AppCompatActivity() {
.eventFlow
.onEach { event ->
when (event) {
is MainEvent.ScreenCaptureSettingChange -> {
handleScreenCaptureSettingChange(event)
}
MainEvent.NavigateToDebugMenu -> navController.navigateToDebugMenuScreen()
is MainEvent.UpdateAppTheme -> {
AppCompatDelegate.setDefaultNightMode(event.osTheme)
@ -123,8 +120,8 @@ class MainActivity : AppCompatActivity() {
mainViewModel.trySendAction(MainAction.OpenDebugMenu)
}
private fun handleScreenCaptureSettingChange(event: MainEvent.ScreenCaptureSettingChange) {
if (event.isAllowed) {
private fun updateScreenCapture(isScreenCaptureAllowed: Boolean) {
if (isScreenCaptureAllowed) {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)

View File

@ -26,6 +26,7 @@ class MainViewModel @Inject constructor(
) : BaseViewModel<MainState, MainEvent, MainAction>(
MainState(
theme = settingsRepository.appTheme,
isScreenCaptureAllowed = settingsRepository.isScreenCaptureAllowed,
isDynamicColorsEnabled = settingsRepository.isDynamicColorsEnabled,
),
) {
@ -43,9 +44,10 @@ class MainViewModel @Inject constructor(
.launchIn(viewModelScope)
settingsRepository
.isScreenCaptureAllowedStateFlow
.map { MainEvent.ScreenCaptureSettingChange(it) }
.onEach(::sendEvent)
.map { MainAction.Internal.ScreenCaptureUpdate(it) }
.onEach(::sendAction)
.launchIn(viewModelScope)
viewModelScope.launch {
configRepository.getServerConfig(forceRefresh = false)
}
@ -64,6 +66,10 @@ class MainViewModel @Inject constructor(
when (action) {
is MainAction.Internal.DynamicColorUpdate -> handleDynamicColorUpdate(action)
is MainAction.Internal.ThemeUpdate -> handleThemeUpdated(action)
is MainAction.Internal.ScreenCaptureUpdate -> handleScreenCaptureUpdate(
screenCaptureUpdateAction = action,
)
}
}
@ -94,6 +100,16 @@ class MainViewModel @Inject constructor(
)
}
private fun handleScreenCaptureUpdate(
screenCaptureUpdateAction: MainAction.Internal.ScreenCaptureUpdate,
) {
mutableStateFlow.update {
it.copy(
isScreenCaptureAllowed = screenCaptureUpdateAction.isScreenCaptureEnabled,
)
}
}
private fun handleIntent(
intent: Intent,
isFirstIntent: Boolean,
@ -109,6 +125,7 @@ class MainViewModel @Inject constructor(
data class MainState(
val theme: AppTheme,
val isDynamicColorsEnabled: Boolean,
val isScreenCaptureAllowed: Boolean,
) : Parcelable
/**
@ -147,6 +164,13 @@ sealed class MainAction {
data class ThemeUpdate(
val theme: AppTheme,
) : Internal()
/**
* Indicates that the screen capture state has changed.
*/
data class ScreenCaptureUpdate(
val isScreenCaptureEnabled: Boolean,
) : Internal()
}
}
@ -160,11 +184,6 @@ sealed class MainEvent {
*/
data object NavigateToDebugMenu : MainEvent()
/**
* Event indicating a change in the screen capture setting.
*/
data class ScreenCaptureSettingChange(val isAllowed: Boolean) : MainEvent()
/**
* Indicates that the app theme has been updated.
*/

View File

@ -22,6 +22,7 @@ class MainViewModelTest : BaseViewModelTest() {
every { appTheme } returns AppTheme.DEFAULT
every { appThemeStateFlow } returns mutableAppThemeFlow
every { isScreenCaptureAllowedStateFlow } returns mutableScreenCaptureAllowedFlow
every { isScreenCaptureAllowed } returns false
every { isDynamicColorsEnabled } returns false
every { isDynamicColorsEnabledFlow } returns mutableIsDynamicColorsEnabledFlow
}
@ -31,7 +32,7 @@ class MainViewModelTest : BaseViewModelTest() {
fun `on AppThemeChanged should update state`() = runTest {
val viewModel = createViewModel()
viewModel.stateEventFlow(backgroundScope) { stateFlow, eventFlow ->
eventFlow.skipItems(count = 2)
eventFlow.skipItems(count = 1)
assertEquals(
DEFAULT_STATE,
stateFlow.awaitItem(),
@ -79,12 +80,29 @@ class MainViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
viewModel.eventFlow.test {
// Ignore the events that are fired off by flows in the ViewModel init
skipItems(2)
skipItems(1)
viewModel.trySendAction(MainAction.OpenDebugMenu)
assertEquals(MainEvent.NavigateToDebugMenu, awaitItem())
}
}
@Test
fun `changes in the allowed screen capture value should update the state`() {
val viewModel = createViewModel()
assertEquals(
DEFAULT_STATE.copy(isScreenCaptureAllowed = false),
viewModel.stateFlow.value,
)
mutableScreenCaptureAllowedFlow.value = true
assertEquals(
DEFAULT_STATE.copy(isScreenCaptureAllowed = true),
viewModel.stateFlow.value,
)
}
private fun createViewModel(): MainViewModel =
MainViewModel(
settingsRepository = settingsRepository,
@ -95,4 +113,5 @@ class MainViewModelTest : BaseViewModelTest() {
private val DEFAULT_STATE = MainState(
theme = AppTheme.DEFAULT,
isDynamicColorsEnabled = false,
isScreenCaptureAllowed = false,
)