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.statusbar.notification.collection.GroupEntry 20 import com.android.systemui.statusbar.notification.collection.ListEntry 21 import com.android.systemui.statusbar.notification.collection.NotifPipeline 22 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope 23 import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProviderImpl 24 import com.android.systemui.statusbar.policy.KeyguardStateController 25 import javax.inject.Inject 26 27 /** Decides if a Notification can be dismissed by the user. */ 28 @CoordinatorScope 29 class DismissibilityCoordinator 30 @Inject 31 constructor( 32 private val keyguardStateController: KeyguardStateController, 33 private val provider: NotificationDismissibilityProviderImpl 34 ) : Coordinator { 35 36 override fun attach(pipeline: NotifPipeline) { 37 pipeline.addOnBeforeRenderListListener(::onBeforeRenderListListener) 38 } 39 40 private fun onBeforeRenderListListener(entries: List<ListEntry>) { 41 val isLocked = !keyguardStateController.isUnlocked 42 val nonDismissableEntryKeys = mutableSetOf<String>() 43 markNonDismissibleEntries(nonDismissableEntryKeys, entries, isLocked) 44 provider.update(nonDismissableEntryKeys) 45 } 46 47 /** 48 * Visits every entry and its children to mark the dismissible entries. 49 * 50 * @param markedKeys set to store the marked entry keys 51 * @param entries to visit 52 * @param isLocked the locked state of the device 53 * @return true if any of the entries were marked as non-dismissible. 54 */ 55 private fun markNonDismissibleEntries( 56 markedKeys: MutableSet<String>, 57 entries: List<ListEntry>, 58 isLocked: Boolean 59 ): Boolean { 60 var anyNonDismissableEntries = false 61 62 for (entry in entries) { 63 entry.representativeEntry?.let { notifEntry -> 64 // mark the entry if it is non-dismissible 65 if (!notifEntry.isDismissableForState(isLocked)) { 66 markedKeys.add(notifEntry.key) 67 anyNonDismissableEntries = true 68 } 69 } 70 71 if (entry is GroupEntry) { 72 if (markNonDismissibleEntries(markedKeys, entry.children, isLocked)) { 73 // if any child is non-dismissible, mark the parent as well 74 entry.representativeEntry?.let { markedKeys.add(it.key) } 75 anyNonDismissableEntries = true 76 } 77 } 78 } 79 80 return anyNonDismissableEntries 81 } 82 } 83