1 /* <lambda>null2 * Copyright (C) 2024 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.scene.domain.interactor 18 19 import com.android.compose.animation.scene.ContentKey 20 import com.android.compose.animation.scene.UserAction 21 import com.android.compose.animation.scene.UserActionResult 22 import com.android.systemui.scene.shared.model.Overlays 23 import com.android.systemui.scene.shared.model.Scenes 24 import com.android.systemui.statusbar.disableflags.domain.interactor.DisableFlagsInteractor 25 import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel 26 import javax.inject.Inject 27 import kotlinx.coroutines.flow.Flow 28 import kotlinx.coroutines.flow.collectLatest 29 import kotlinx.coroutines.flow.combine 30 import kotlinx.coroutines.flow.distinctUntilChanged 31 import kotlinx.coroutines.flow.map 32 33 class DisabledContentInteractor 34 @Inject 35 constructor(private val disableFlagsInteractor: DisableFlagsInteractor) { 36 37 /** Returns `true` if the given [key] is disabled; `false` if it's enabled */ 38 fun isDisabled( 39 key: ContentKey, 40 disabledFlags: DisableFlagsModel = disableFlagsInteractor.disableFlags.value, 41 ): Boolean { 42 return with(disabledFlags) { 43 when (key) { 44 Scenes.Shade, 45 Overlays.NotificationsShade -> !isShadeEnabled() 46 Scenes.QuickSettings, 47 Overlays.QuickSettingsShade -> !isQuickSettingsEnabled() 48 else -> false 49 } 50 } 51 } 52 53 /** Runs the given [block] each time that [key] becomes disabled. */ 54 suspend fun repeatWhenDisabled(key: ContentKey, block: suspend (disabled: ContentKey) -> Unit) { 55 disableFlagsInteractor.disableFlags 56 .map { isDisabled(key) } 57 .distinctUntilChanged() 58 .collectLatest { isDisabled -> 59 if (isDisabled) { 60 block(key) 61 } 62 } 63 } 64 65 /** 66 * Returns a filtered version of [unfiltered], without action-result entries that would navigate 67 * to disabled scenes. 68 */ 69 fun filteredUserActions( 70 unfiltered: Flow<Map<UserAction, UserActionResult>> 71 ): Flow<Map<UserAction, UserActionResult>> { 72 return combine(disableFlagsInteractor.disableFlags, unfiltered) { 73 disabledFlags, 74 unfilteredMap -> 75 unfilteredMap.filterValues { actionResult -> 76 val destination = 77 when (actionResult) { 78 is UserActionResult.ChangeScene -> actionResult.toScene 79 is UserActionResult.ShowOverlay -> actionResult.overlay 80 is UserActionResult.ReplaceByOverlay -> actionResult.overlay 81 else -> null 82 } 83 if (destination != null) { 84 // results that lead to a disabled destination get filtered out. 85 !isDisabled(key = destination, disabledFlags = disabledFlags) 86 } else { 87 // Action results that don't lead to a destination are never filtered out. 88 true 89 } 90 } 91 } 92 } 93 } 94