diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt index 607500edfd3a5..c35b77cfb4e06 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt @@ -22,6 +22,7 @@ import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection +import com.android.systemui.util.Compile import com.android.systemui.util.traceSection /** @@ -37,8 +38,11 @@ class NodeSpecBuilder( private val mediaContainerController: MediaContainerController, private val sectionsFeatureManager: NotificationSectionsFeatureManager, private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider, - private val viewBarn: NotifViewBarn + private val viewBarn: NotifViewBarn, + private val logger: NodeSpecBuilderLogger ) { + private var lastSections = setOf() + fun buildNodeSpec( rootController: NodeController, notifList: List @@ -54,6 +58,9 @@ class NodeSpecBuilder( var currentSection: NotifSection? = null val prevSections = mutableSetOf() val showHeaders = sectionHeaderVisibilityProvider.sectionHeadersVisible + val sectionOrder = mutableListOf() + val sectionHeaders = mutableMapOf() + val sectionCounts = mutableMapOf() for (entry in notifList) { val section = entry.section!! @@ -67,14 +74,28 @@ class NodeSpecBuilder( if (section.headerController != currentSection?.headerController && showHeaders) { section.headerController?.let { headerController -> root.children.add(NodeSpecImpl(root, headerController)) + if (Compile.IS_DEBUG) { + sectionHeaders[section] = headerController + } } } prevSections.add(currentSection) currentSection = section + if (Compile.IS_DEBUG) { + sectionOrder.add(section) + } } // Finally, add the actual notif node! root.children.add(buildNotifNode(root, entry)) + if (Compile.IS_DEBUG) { + sectionCounts[section] = sectionCounts.getOrDefault(section, 0) + 1 + } + } + + if (Compile.IS_DEBUG) { + logger.logBuildNodeSpec(lastSections, sectionHeaders, sectionCounts, sectionOrder) + lastSections = sectionCounts.keys } return@traceSection root @@ -87,4 +108,4 @@ class NodeSpecBuilder( .apply { entry.children.forEach { children.add(buildNotifNode(this, it)) } } else -> throw RuntimeException("Unexpected entry: $entry") } -} +} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt new file mode 100644 index 0000000000000..3501b44a2c2e2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 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.render + +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogLevel +import com.android.systemui.log.dagger.NotificationLog +import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection +import com.android.systemui.util.Compile +import javax.inject.Inject + +class NodeSpecBuilderLogger @Inject constructor( + @NotificationLog private val buffer: LogBuffer +) { + fun logBuildNodeSpec( + oldSections: Set, + newHeaders: Map, + newCounts: Map, + newSectionOrder: List + ) { + if (!Compile.IS_DEBUG) + return + + buffer.log(TAG, LogLevel.DEBUG, { + int1 = newSectionOrder.size + }, { "buildNodeSpec finished with $int1 sections" }) + + for (section in newSectionOrder) { + buffer.log(TAG, LogLevel.DEBUG, { + str1 = section?.sectioner?.name ?: "(null)" + str2 = newHeaders[section]?.nodeLabel ?: "(none)" + int1 = newCounts[section] ?: -1 + }, { + " section $str1 has header $str2, $int1 entries" + }) + } + + for (section in oldSections - newSectionOrder.toSet()) { + buffer.log(TAG, LogLevel.DEBUG, { + str1 = section?.sectioner?.name ?: "(null)" + }, { + " section $str1 was removed since last run" + }) + } + } +} + +private const val TAG = "NodeSpecBuilder" \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt index 484707241b4d4..6ed81078c3a4a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt @@ -40,15 +40,16 @@ class ShadeViewManager @AssistedInject constructor( mediaContainerController: MediaContainerController, featureManager: NotificationSectionsFeatureManager, sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider, - logger: ShadeViewDifferLogger, + nodeSpecBuilderLogger: NodeSpecBuilderLogger, + shadeViewDifferLogger: ShadeViewDifferLogger, private val viewBarn: NotifViewBarn ) { // We pass a shim view here because the listContainer may not actually have a view associated // with it and the differ never actually cares about the root node's view. private val rootController = RootNodeController(listContainer, View(context)) private val specBuilder = NodeSpecBuilder(mediaContainerController, featureManager, - sectionHeaderVisibilityProvider, viewBarn) - private val viewDiffer = ShadeViewDiffer(rootController, logger) + sectionHeaderVisibilityProvider, viewBarn, nodeSpecBuilderLogger) + private val viewDiffer = ShadeViewDiffer(rootController, shadeViewDifferLogger) /** Method for attaching this manager to the pipeline. */ fun attach(renderStageManager: RenderStageManager) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt index 4e309d49c6d2c..0e1865861caea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt @@ -46,6 +46,7 @@ class NodeSpecBuilderTest : SysuiTestCase() { private val sectionsFeatureManager: NotificationSectionsFeatureManager = mock() private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider = mock() private val viewBarn: NotifViewBarn = mock() + private val logger: NodeSpecBuilderLogger = mock() private var rootController: NodeController = buildFakeController("rootController") private var headerController0: NodeController = buildFakeController("header0") @@ -75,7 +76,7 @@ class NodeSpecBuilderTest : SysuiTestCase() { } specBuilder = NodeSpecBuilder(mediaContainerController, sectionsFeatureManager, - sectionHeaderVisibilityProvider, viewBarn) + sectionHeaderVisibilityProvider, viewBarn, logger) } @Test