1 /* <lambda>null2 * Copyright (C) 2023 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.statusbar.notification.collection.coordinator 18 19 import com.android.systemui.dagger.qualifiers.Application 20 import com.android.systemui.keyguard.data.repository.KeyguardRepository 21 import com.android.systemui.plugins.statusbar.StatusBarStateController 22 import com.android.systemui.statusbar.StatusBarState 23 import com.android.systemui.statusbar.SysuiStatusBarStateController 24 import com.android.systemui.statusbar.notification.collection.NotifPipeline 25 import com.android.systemui.statusbar.notification.collection.NotificationEntry 26 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope 27 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter 28 import javax.inject.Inject 29 import kotlinx.coroutines.CoroutineScope 30 import kotlinx.coroutines.launch 31 32 /** 33 * Filter out notifications on the lockscreen if the lockscreen hosted dream is active. If the user 34 * stops dreaming, pulls the shade down or unlocks the device, then the notifications are unhidden. 35 */ 36 @CoordinatorScope 37 class DreamCoordinator 38 @Inject 39 constructor( 40 private val statusBarStateController: SysuiStatusBarStateController, 41 @Application private val scope: CoroutineScope, 42 private val keyguardRepository: KeyguardRepository, 43 ) : Coordinator { 44 private var isOnKeyguard = false 45 private var isLockscreenHostedDream = false 46 47 override fun attach(pipeline: NotifPipeline) { 48 pipeline.addPreGroupFilter(filter) 49 statusBarStateController.addCallback(statusBarStateListener) 50 scope.launch { attachFilterOnDreamingStateChange() } 51 recordStatusBarState(statusBarStateController.state) 52 } 53 54 private val filter = 55 object : NotifFilter("LockscreenHostedDreamFilter") { 56 var isFiltering = false 57 override fun shouldFilterOut(entry: NotificationEntry, now: Long): Boolean { 58 return isFiltering 59 } 60 inline fun update(msg: () -> String) { 61 val wasFiltering = isFiltering 62 isFiltering = isLockscreenHostedDream && isOnKeyguard 63 if (wasFiltering != isFiltering) { 64 invalidateList(msg()) 65 } 66 } 67 } 68 69 private val statusBarStateListener = 70 object : StatusBarStateController.StateListener { 71 override fun onStateChanged(newState: Int) { 72 recordStatusBarState(newState) 73 } 74 } 75 76 private suspend fun attachFilterOnDreamingStateChange() { 77 keyguardRepository.isActiveDreamLockscreenHosted.collect { isDreaming -> 78 recordDreamingState(isDreaming) 79 } 80 } 81 82 private fun recordStatusBarState(newState: Int) { 83 isOnKeyguard = newState == StatusBarState.KEYGUARD 84 filter.update { "recordStatusBarState: " + StatusBarState.toString(newState) } 85 } 86 87 private fun recordDreamingState(isDreaming: Boolean) { 88 isLockscreenHostedDream = isDreaming 89 filter.update { "recordLockscreenHostedDreamState: $isDreaming" } 90 } 91 } 92