Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorLogger.kt +1 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ class GutsCoordinatorLogger @Inject constructor( fun logGutsOpened(key: String, guts: NotificationGuts) { buffer.log(TAG, LogLevel.DEBUG, { str1 = key str2 = guts::class.simpleName str2 = guts.gutsContent::class.simpleName bool1 = guts.isLeavebehind }, { "Guts of type $str2 (leave behind: $bool1) opened for class $str1" Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java +4 −0 Original line number Diff line number Diff line Loading @@ -61,7 +61,9 @@ public class NotifCoordinators implements Dumpable { ConversationCoordinator conversationCoordinator, PreparationCoordinator preparationCoordinator, MediaCoordinator mediaCoordinator, ShadeEventCoordinator shadeEventCoordinator, SmartspaceDedupingCoordinator smartspaceDedupingCoordinator, ViewConfigCoordinator viewConfigCoordinator, VisualStabilityCoordinator visualStabilityCoordinator, CommunalCoordinator communalCoordinator) { dumpManager.registerDumpable(TAG, this); Loading @@ -75,6 +77,8 @@ public class NotifCoordinators implements Dumpable { mCoordinators.add(bubbleCoordinator); mCoordinators.add(conversationCoordinator); mCoordinators.add(mediaCoordinator); mCoordinators.add(shadeEventCoordinator); mCoordinators.add(viewConfigCoordinator); mCoordinators.add(visualStabilityCoordinator); mCoordinators.add(communalCoordinator); Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinator.kt 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.statusbar.notification.collection.coordinator import android.service.notification.NotificationListenerService import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource import javax.inject.Inject /** * A coordinator which provides callbacks to a view surfaces for various events relevant to the * shade, such as when the user removes a notification, or when the shade is emptied. */ @SysUISingleton class ShadeEventCoordinator @Inject internal constructor( private val mLogger: ShadeEventCoordinatorLogger ) : Coordinator, NotifShadeEventSource { private var mNotifRemovedByUserCallback: Runnable? = null private var mShadeEmptiedCallback: Runnable? = null private var mEntryRemoved = false private var mEntryRemovedByUser = false override fun attach(pipeline: NotifPipeline) { pipeline.addCollectionListener(mNotifCollectionListener) pipeline.addOnBeforeRenderListListener(this::onBeforeRenderList) } private val mNotifCollectionListener = object : NotifCollectionListener { override fun onEntryRemoved(entry: NotificationEntry, reason: Int) { mEntryRemoved = true mEntryRemovedByUser = reason == NotificationListenerService.REASON_CLICK || reason == NotificationListenerService.REASON_CANCEL_ALL || reason == NotificationListenerService.REASON_CANCEL } } override fun setNotifRemovedByUserCallback(callback: Runnable) { check(mNotifRemovedByUserCallback == null) { "mNotifRemovedByUserCallback already set" } mNotifRemovedByUserCallback = callback } override fun setShadeEmptiedCallback(callback: Runnable) { check(mShadeEmptiedCallback == null) { "mShadeEmptiedCallback already set" } mShadeEmptiedCallback = callback } private fun onBeforeRenderList(entries: List<ListEntry>) { if (mEntryRemoved && entries.isEmpty()) { mLogger.logShadeEmptied() mShadeEmptiedCallback?.run() } if (mEntryRemoved && mEntryRemovedByUser) { mLogger.logNotifRemovedByUser() mNotifRemovedByUserCallback?.run() } mEntryRemoved = false mEntryRemovedByUser = false } } No newline at end of file packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorLogger.kt 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.statusbar.notification.collection.coordinator import com.android.systemui.log.LogBuffer import com.android.systemui.log.LogLevel import com.android.systemui.log.dagger.NotificationLog import javax.inject.Inject private const val TAG = "ShadeEventCoordinator" /** Logger for the [ShadeEventCoordinator] */ class ShadeEventCoordinatorLogger @Inject constructor( @NotificationLog private val buffer: LogBuffer ) { fun logShadeEmptied() { buffer.log(TAG, LogLevel.DEBUG, { }, { "Shade emptied" }) } fun logNotifRemovedByUser() { buffer.log(TAG, LogLevel.DEBUG, { }, { "Notification removed by user" }) } } packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt 0 → 100644 +109 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.statusbar.notification.collection.coordinator import com.android.internal.widget.MessagingGroup import com.android.internal.widget.MessagingMessage import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.row.NotificationGutsManager import com.android.systemui.statusbar.policy.ConfigurationController import javax.inject.Inject /** * A coordinator which ensures that notifications within the new pipeline are correctly inflated * for the current uiMode and screen properties; additionally deferring those changes when a user * change is in progress until that process has completed. */ @SysUISingleton class ViewConfigCoordinator @Inject internal constructor( configurationController: ConfigurationController, lockscreenUserManager: NotificationLockscreenUserManagerImpl, featureFlags: FeatureFlags, private val mGutsManager: NotificationGutsManager, private val mKeyguardUpdateMonitor: KeyguardUpdateMonitor ) : Coordinator, UserChangedListener, ConfigurationController.ConfigurationListener { private var mReinflateNotificationsOnUserSwitched = false private var mDispatchUiModeChangeOnUserSwitched = false private var mPipeline: NotifPipeline? = null init { if (featureFlags.isNewNotifPipelineRenderingEnabled) { lockscreenUserManager.addUserChangedListener(this) configurationController.addCallback(this) } } override fun attach(pipeline: NotifPipeline) { mPipeline = pipeline } override fun onDensityOrFontScaleChanged() { MessagingMessage.dropCache() MessagingGroup.dropCache() if (!mKeyguardUpdateMonitor.isSwitchingUser) { updateNotificationsOnDensityOrFontScaleChanged() } else { mReinflateNotificationsOnUserSwitched = true } } override fun onUiModeChanged() { if (!mKeyguardUpdateMonitor.isSwitchingUser) { updateNotificationsOnUiModeChanged() } else { mDispatchUiModeChangeOnUserSwitched = true } } override fun onThemeChanged() { onDensityOrFontScaleChanged() } override fun onUserChanged(userId: Int) { if (mReinflateNotificationsOnUserSwitched) { updateNotificationsOnDensityOrFontScaleChanged() mReinflateNotificationsOnUserSwitched = false } if (mDispatchUiModeChangeOnUserSwitched) { updateNotificationsOnUiModeChanged() mDispatchUiModeChangeOnUserSwitched = false } } private fun updateNotificationsOnUiModeChanged() { mPipeline?.allNotifs?.forEach { entry -> val row = entry.row row?.onUiModeChanged() } } private fun updateNotificationsOnDensityOrFontScaleChanged() { mPipeline?.allNotifs?.forEach { entry -> entry.onDensityOrFontScaleChanged() val exposedGuts = entry.areGutsExposed() if (exposedGuts) { mGutsManager.onDensityOrFontScaleChanged(entry) } } } } No newline at end of file Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorLogger.kt +1 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ class GutsCoordinatorLogger @Inject constructor( fun logGutsOpened(key: String, guts: NotificationGuts) { buffer.log(TAG, LogLevel.DEBUG, { str1 = key str2 = guts::class.simpleName str2 = guts.gutsContent::class.simpleName bool1 = guts.isLeavebehind }, { "Guts of type $str2 (leave behind: $bool1) opened for class $str1" Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java +4 −0 Original line number Diff line number Diff line Loading @@ -61,7 +61,9 @@ public class NotifCoordinators implements Dumpable { ConversationCoordinator conversationCoordinator, PreparationCoordinator preparationCoordinator, MediaCoordinator mediaCoordinator, ShadeEventCoordinator shadeEventCoordinator, SmartspaceDedupingCoordinator smartspaceDedupingCoordinator, ViewConfigCoordinator viewConfigCoordinator, VisualStabilityCoordinator visualStabilityCoordinator, CommunalCoordinator communalCoordinator) { dumpManager.registerDumpable(TAG, this); Loading @@ -75,6 +77,8 @@ public class NotifCoordinators implements Dumpable { mCoordinators.add(bubbleCoordinator); mCoordinators.add(conversationCoordinator); mCoordinators.add(mediaCoordinator); mCoordinators.add(shadeEventCoordinator); mCoordinators.add(viewConfigCoordinator); mCoordinators.add(visualStabilityCoordinator); mCoordinators.add(communalCoordinator); Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinator.kt 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.statusbar.notification.collection.coordinator import android.service.notification.NotificationListenerService import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource import javax.inject.Inject /** * A coordinator which provides callbacks to a view surfaces for various events relevant to the * shade, such as when the user removes a notification, or when the shade is emptied. */ @SysUISingleton class ShadeEventCoordinator @Inject internal constructor( private val mLogger: ShadeEventCoordinatorLogger ) : Coordinator, NotifShadeEventSource { private var mNotifRemovedByUserCallback: Runnable? = null private var mShadeEmptiedCallback: Runnable? = null private var mEntryRemoved = false private var mEntryRemovedByUser = false override fun attach(pipeline: NotifPipeline) { pipeline.addCollectionListener(mNotifCollectionListener) pipeline.addOnBeforeRenderListListener(this::onBeforeRenderList) } private val mNotifCollectionListener = object : NotifCollectionListener { override fun onEntryRemoved(entry: NotificationEntry, reason: Int) { mEntryRemoved = true mEntryRemovedByUser = reason == NotificationListenerService.REASON_CLICK || reason == NotificationListenerService.REASON_CANCEL_ALL || reason == NotificationListenerService.REASON_CANCEL } } override fun setNotifRemovedByUserCallback(callback: Runnable) { check(mNotifRemovedByUserCallback == null) { "mNotifRemovedByUserCallback already set" } mNotifRemovedByUserCallback = callback } override fun setShadeEmptiedCallback(callback: Runnable) { check(mShadeEmptiedCallback == null) { "mShadeEmptiedCallback already set" } mShadeEmptiedCallback = callback } private fun onBeforeRenderList(entries: List<ListEntry>) { if (mEntryRemoved && entries.isEmpty()) { mLogger.logShadeEmptied() mShadeEmptiedCallback?.run() } if (mEntryRemoved && mEntryRemovedByUser) { mLogger.logNotifRemovedByUser() mNotifRemovedByUserCallback?.run() } mEntryRemoved = false mEntryRemovedByUser = false } } No newline at end of file
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorLogger.kt 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.statusbar.notification.collection.coordinator import com.android.systemui.log.LogBuffer import com.android.systemui.log.LogLevel import com.android.systemui.log.dagger.NotificationLog import javax.inject.Inject private const val TAG = "ShadeEventCoordinator" /** Logger for the [ShadeEventCoordinator] */ class ShadeEventCoordinatorLogger @Inject constructor( @NotificationLog private val buffer: LogBuffer ) { fun logShadeEmptied() { buffer.log(TAG, LogLevel.DEBUG, { }, { "Shade emptied" }) } fun logNotifRemovedByUser() { buffer.log(TAG, LogLevel.DEBUG, { }, { "Notification removed by user" }) } }
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt 0 → 100644 +109 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.statusbar.notification.collection.coordinator import com.android.internal.widget.MessagingGroup import com.android.internal.widget.MessagingMessage import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.row.NotificationGutsManager import com.android.systemui.statusbar.policy.ConfigurationController import javax.inject.Inject /** * A coordinator which ensures that notifications within the new pipeline are correctly inflated * for the current uiMode and screen properties; additionally deferring those changes when a user * change is in progress until that process has completed. */ @SysUISingleton class ViewConfigCoordinator @Inject internal constructor( configurationController: ConfigurationController, lockscreenUserManager: NotificationLockscreenUserManagerImpl, featureFlags: FeatureFlags, private val mGutsManager: NotificationGutsManager, private val mKeyguardUpdateMonitor: KeyguardUpdateMonitor ) : Coordinator, UserChangedListener, ConfigurationController.ConfigurationListener { private var mReinflateNotificationsOnUserSwitched = false private var mDispatchUiModeChangeOnUserSwitched = false private var mPipeline: NotifPipeline? = null init { if (featureFlags.isNewNotifPipelineRenderingEnabled) { lockscreenUserManager.addUserChangedListener(this) configurationController.addCallback(this) } } override fun attach(pipeline: NotifPipeline) { mPipeline = pipeline } override fun onDensityOrFontScaleChanged() { MessagingMessage.dropCache() MessagingGroup.dropCache() if (!mKeyguardUpdateMonitor.isSwitchingUser) { updateNotificationsOnDensityOrFontScaleChanged() } else { mReinflateNotificationsOnUserSwitched = true } } override fun onUiModeChanged() { if (!mKeyguardUpdateMonitor.isSwitchingUser) { updateNotificationsOnUiModeChanged() } else { mDispatchUiModeChangeOnUserSwitched = true } } override fun onThemeChanged() { onDensityOrFontScaleChanged() } override fun onUserChanged(userId: Int) { if (mReinflateNotificationsOnUserSwitched) { updateNotificationsOnDensityOrFontScaleChanged() mReinflateNotificationsOnUserSwitched = false } if (mDispatchUiModeChangeOnUserSwitched) { updateNotificationsOnUiModeChanged() mDispatchUiModeChangeOnUserSwitched = false } } private fun updateNotificationsOnUiModeChanged() { mPipeline?.allNotifs?.forEach { entry -> val row = entry.row row?.onUiModeChanged() } } private fun updateNotificationsOnDensityOrFontScaleChanged() { mPipeline?.allNotifs?.forEach { entry -> entry.onDensityOrFontScaleChanged() val exposedGuts = entry.areGutsExposed() if (exposedGuts) { mGutsManager.onDensityOrFontScaleChanged(entry) } } } } No newline at end of file