Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +58 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.statusbar; import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT; import android.content.Context; import android.content.res.Resources; import android.os.Handler; Loading @@ -39,6 +41,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.legacy.LowPriorityInflationHelper; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.render.NotifStackController; import com.android.systemui.statusbar.notification.collection.render.NotifStats; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; Loading Loading @@ -97,6 +101,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle private final Context mContext; private NotificationPresenter mPresenter; private NotifStackController mStackController; private NotificationListContainer mListContainer; // Used to help track down re-entrant calls to our update methods, which will cause bugs. Loading Loading @@ -147,8 +152,10 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle } public void setUpWithPresenter(NotificationPresenter presenter, NotifStackController stackController, NotificationListContainer listContainer) { mPresenter = presenter; mStackController = stackController; mListContainer = listContainer; if (!mNotifPipelineFlags.isNewPipelineEnabled()) { mDynamicPrivacyController.addListener(this); Loading Loading @@ -328,12 +335,62 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle mTmpChildOrderMap.clear(); updateRowStatesInternal(); updateNotifStats(); mListContainer.onNotificationViewUpdateFinished(); endUpdate(); } /** * In the spirit of unidirectional data flow, calculate this information when the notification * views are updated, and set it once, speeding up lookups later. * This is analogous to logic in the * {@link com.android.systemui.statusbar.notification.collection.coordinator.StackCoordinator} */ private void updateNotifStats() { boolean hasNonClearableAlertingNotifs = false; boolean hasClearableAlertingNotifs = false; boolean hasNonClearableSilentNotifs = false; boolean hasClearableSilentNotifs = false; final int childCount = mListContainer.getContainerChildCount(); int visibleTopLevelEntries = 0; for (int i = 0; i < childCount; i++) { View child = mListContainer.getContainerChildAt(i); if (child == null || child.getVisibility() == View.GONE) { continue; } if (!(child instanceof ExpandableNotificationRow)) { continue; } final ExpandableNotificationRow row = (ExpandableNotificationRow) child; boolean isSilent = row.getEntry().getBucket() == BUCKET_SILENT; // NOTE: NotificationEntry.isClearable() will internally check group children to ensure // the group itself definitively clearable. boolean isClearable = row.getEntry().isClearable(); if (isSilent) { if (isClearable) { hasClearableSilentNotifs = true; } else { // !isClearable hasNonClearableSilentNotifs = true; } } else { // !isSilent if (isClearable) { hasClearableAlertingNotifs = true; } else { // !isClearable hasNonClearableAlertingNotifs = true; } } } mStackController.setNotifStats(new NotifStats( visibleTopLevelEntries /* numActiveNotifs */, hasNonClearableAlertingNotifs /* hasNonClearableAlertingNotifs */, hasClearableAlertingNotifs /* hasClearableAlertingNotifs */, hasNonClearableSilentNotifs /* hasNonClearableSilentNotifs */, hasClearableSilentNotifs /* hasClearableSilentNotifs */ )); } /** * Should a notification entry from the active list be suppressed and not show? */ Loading Loading @@ -528,9 +585,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle @Override public void onDynamicPrivacyChanged() { if (mNotifPipelineFlags.isNewPipelineEnabled()) { throw new IllegalStateException("Old pipeline code running w/ new pipeline enabled"); } mNotifPipelineFlags.assertLegacyPipelineEnabled(); if (mPerformingUpdate) { Log.w(TAG, "onDynamicPrivacyChanged made a re-entrant call"); } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt +10 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ class NotifPipelineFlags @Inject constructor( val featureFlags: FeatureFlags ) { fun checkLegacyPipelineEnabled(): Boolean { if (!featureFlags.isEnabled(Flags.NEW_NOTIFICATION_PIPELINE_RENDERING)) { if (!isNewPipelineEnabled()) { return true } Log.d("NotifPipeline", "Old pipeline code running w/ new pipeline enabled", Exception()) Loading @@ -36,10 +36,13 @@ class NotifPipelineFlags @Inject constructor( return false } fun isNewPipelineEnabled(): Boolean = featureFlags.isEnabled( Flags.NEW_NOTIFICATION_PIPELINE_RENDERING) fun assertLegacyPipelineEnabled(): Nothing = error("Old pipeline code running w/ new pipeline enabled") fun isNewPipelineEnabled(): Boolean = featureFlags.isEnabled(Flags.NEW_NOTIFICATION_PIPELINE_RENDERING) fun isSmartspaceDedupingEnabled(): Boolean = featureFlags.isEnabled(Flags.SMARTSPACE) && featureFlags.isEnabled(Flags.SMARTSPACE_DEDUPING) featureFlags.isEnabled(Flags.SMARTSPACE) && featureFlags.isEnabled(Flags.SMARTSPACE_DEDUPING) } No newline at end of file packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java +0 −20 Original line number Diff line number Diff line Loading @@ -19,8 +19,6 @@ package com.android.systemui.statusbar.notification.collection; import android.annotation.NonNull; import android.annotation.Nullable; import com.android.systemui.statusbar.notification.collection.coordinator.PreparationCoordinator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; Loading Loading @@ -61,24 +59,6 @@ public class GroupEntry extends ListEntry { mSummary = summary; } /** * @see #getUntruncatedChildCount() */ public void setUntruncatedChildCount(int childCount) { mUntruncatedChildCount = childCount; } /** * Get the untruncated number of children from the data model, including those that will not * have views bound. This includes children that {@link PreparationCoordinator} will filter out * entirely when they are beyond the last visible child. * * TODO: This should move to some shared class between the model and view hierarchy */ public int getUntruncatedChildCount() { return mUntruncatedChildCount; } void clearChildren() { mChildren.clear(); } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java +1 −1 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ public class NotifInflaterImpl implements NotifInflater { public void onAsyncInflationFinished(NotificationEntry entry) { mNotifErrorManager.clearInflationError(entry); if (callback != null) { callback.onInflationFinished(entry); callback.onInflationFinished(entry, entry.getRowController()); } } }; Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt +31 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.notification.collection import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener Loading @@ -31,6 +34,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.In import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender import com.android.systemui.statusbar.notification.collection.render.RenderStageManager import javax.inject.Inject /** Loading Loading @@ -65,11 +69,15 @@ import javax.inject.Inject * 9. Finalize filters are fired on each notification ([.addFinalizeFilter]) * 10. OnBeforeRenderListListeners are fired ([.addOnBeforeRenderListListener]) * 11. The list is handed off to the view layer to be rendered * 12. OnAfterRenderListListeners are fired ([.addOnAfterRenderListListener]) * 13. OnAfterRenderGroupListeners are fired ([.addOnAfterRenderGroupListener]) * 13. OnAfterRenderEntryListeners are fired ([.addOnAfterRenderEntryListener]) */ @SysUISingleton class NotifPipeline @Inject constructor( private val mNotifCollection: NotifCollection, private val mShadeListBuilder: ShadeListBuilder private val mShadeListBuilder: ShadeListBuilder, private val mRenderStageManager: RenderStageManager ) : CommonNotifCollection { /** * Returns the list of all known notifications, i.e. the notifications that are currently posted Loading Loading @@ -205,6 +213,28 @@ class NotifPipeline @Inject constructor( mShadeListBuilder.addPreRenderInvalidator(invalidator) } /** * Called at the end of the pipeline after the notif list has been handed off to the view layer. */ fun addOnAfterRenderListListener(listener: OnAfterRenderListListener) { mRenderStageManager.addOnAfterRenderListListener(listener) } /** * Called at the end of the pipeline after a group has been handed off to the view layer. */ fun addOnAfterRenderGroupListener(listener: OnAfterRenderGroupListener) { mRenderStageManager.addOnAfterRenderGroupListener(listener) } /** * Called at the end of the pipeline after an entry has been handed off to the view layer. * This will be called for every top level entry, every group summary, and every group child. */ fun addOnAfterRenderEntryListener(listener: OnAfterRenderEntryListener) { mRenderStageManager.addOnAfterRenderEntryListener(listener) } /** * Get an object which can be used to update a notification (internally to the pipeline) * in response to a user action. Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +58 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.statusbar; import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT; import android.content.Context; import android.content.res.Resources; import android.os.Handler; Loading @@ -39,6 +41,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.legacy.LowPriorityInflationHelper; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.render.NotifStackController; import com.android.systemui.statusbar.notification.collection.render.NotifStats; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; Loading Loading @@ -97,6 +101,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle private final Context mContext; private NotificationPresenter mPresenter; private NotifStackController mStackController; private NotificationListContainer mListContainer; // Used to help track down re-entrant calls to our update methods, which will cause bugs. Loading Loading @@ -147,8 +152,10 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle } public void setUpWithPresenter(NotificationPresenter presenter, NotifStackController stackController, NotificationListContainer listContainer) { mPresenter = presenter; mStackController = stackController; mListContainer = listContainer; if (!mNotifPipelineFlags.isNewPipelineEnabled()) { mDynamicPrivacyController.addListener(this); Loading Loading @@ -328,12 +335,62 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle mTmpChildOrderMap.clear(); updateRowStatesInternal(); updateNotifStats(); mListContainer.onNotificationViewUpdateFinished(); endUpdate(); } /** * In the spirit of unidirectional data flow, calculate this information when the notification * views are updated, and set it once, speeding up lookups later. * This is analogous to logic in the * {@link com.android.systemui.statusbar.notification.collection.coordinator.StackCoordinator} */ private void updateNotifStats() { boolean hasNonClearableAlertingNotifs = false; boolean hasClearableAlertingNotifs = false; boolean hasNonClearableSilentNotifs = false; boolean hasClearableSilentNotifs = false; final int childCount = mListContainer.getContainerChildCount(); int visibleTopLevelEntries = 0; for (int i = 0; i < childCount; i++) { View child = mListContainer.getContainerChildAt(i); if (child == null || child.getVisibility() == View.GONE) { continue; } if (!(child instanceof ExpandableNotificationRow)) { continue; } final ExpandableNotificationRow row = (ExpandableNotificationRow) child; boolean isSilent = row.getEntry().getBucket() == BUCKET_SILENT; // NOTE: NotificationEntry.isClearable() will internally check group children to ensure // the group itself definitively clearable. boolean isClearable = row.getEntry().isClearable(); if (isSilent) { if (isClearable) { hasClearableSilentNotifs = true; } else { // !isClearable hasNonClearableSilentNotifs = true; } } else { // !isSilent if (isClearable) { hasClearableAlertingNotifs = true; } else { // !isClearable hasNonClearableAlertingNotifs = true; } } } mStackController.setNotifStats(new NotifStats( visibleTopLevelEntries /* numActiveNotifs */, hasNonClearableAlertingNotifs /* hasNonClearableAlertingNotifs */, hasClearableAlertingNotifs /* hasClearableAlertingNotifs */, hasNonClearableSilentNotifs /* hasNonClearableSilentNotifs */, hasClearableSilentNotifs /* hasClearableSilentNotifs */ )); } /** * Should a notification entry from the active list be suppressed and not show? */ Loading Loading @@ -528,9 +585,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle @Override public void onDynamicPrivacyChanged() { if (mNotifPipelineFlags.isNewPipelineEnabled()) { throw new IllegalStateException("Old pipeline code running w/ new pipeline enabled"); } mNotifPipelineFlags.assertLegacyPipelineEnabled(); if (mPerformingUpdate) { Log.w(TAG, "onDynamicPrivacyChanged made a re-entrant call"); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt +10 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ class NotifPipelineFlags @Inject constructor( val featureFlags: FeatureFlags ) { fun checkLegacyPipelineEnabled(): Boolean { if (!featureFlags.isEnabled(Flags.NEW_NOTIFICATION_PIPELINE_RENDERING)) { if (!isNewPipelineEnabled()) { return true } Log.d("NotifPipeline", "Old pipeline code running w/ new pipeline enabled", Exception()) Loading @@ -36,10 +36,13 @@ class NotifPipelineFlags @Inject constructor( return false } fun isNewPipelineEnabled(): Boolean = featureFlags.isEnabled( Flags.NEW_NOTIFICATION_PIPELINE_RENDERING) fun assertLegacyPipelineEnabled(): Nothing = error("Old pipeline code running w/ new pipeline enabled") fun isNewPipelineEnabled(): Boolean = featureFlags.isEnabled(Flags.NEW_NOTIFICATION_PIPELINE_RENDERING) fun isSmartspaceDedupingEnabled(): Boolean = featureFlags.isEnabled(Flags.SMARTSPACE) && featureFlags.isEnabled(Flags.SMARTSPACE_DEDUPING) featureFlags.isEnabled(Flags.SMARTSPACE) && featureFlags.isEnabled(Flags.SMARTSPACE_DEDUPING) } No newline at end of file
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java +0 −20 Original line number Diff line number Diff line Loading @@ -19,8 +19,6 @@ package com.android.systemui.statusbar.notification.collection; import android.annotation.NonNull; import android.annotation.Nullable; import com.android.systemui.statusbar.notification.collection.coordinator.PreparationCoordinator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; Loading Loading @@ -61,24 +59,6 @@ public class GroupEntry extends ListEntry { mSummary = summary; } /** * @see #getUntruncatedChildCount() */ public void setUntruncatedChildCount(int childCount) { mUntruncatedChildCount = childCount; } /** * Get the untruncated number of children from the data model, including those that will not * have views bound. This includes children that {@link PreparationCoordinator} will filter out * entirely when they are beyond the last visible child. * * TODO: This should move to some shared class between the model and view hierarchy */ public int getUntruncatedChildCount() { return mUntruncatedChildCount; } void clearChildren() { mChildren.clear(); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java +1 −1 Original line number Diff line number Diff line Loading @@ -93,7 +93,7 @@ public class NotifInflaterImpl implements NotifInflater { public void onAsyncInflationFinished(NotificationEntry entry) { mNotifErrorManager.clearInflationError(entry); if (callback != null) { callback.onInflationFinished(entry); callback.onInflationFinished(entry, entry.getRowController()); } } }; Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt +31 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.notification.collection import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener Loading @@ -31,6 +34,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.In import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender import com.android.systemui.statusbar.notification.collection.render.RenderStageManager import javax.inject.Inject /** Loading Loading @@ -65,11 +69,15 @@ import javax.inject.Inject * 9. Finalize filters are fired on each notification ([.addFinalizeFilter]) * 10. OnBeforeRenderListListeners are fired ([.addOnBeforeRenderListListener]) * 11. The list is handed off to the view layer to be rendered * 12. OnAfterRenderListListeners are fired ([.addOnAfterRenderListListener]) * 13. OnAfterRenderGroupListeners are fired ([.addOnAfterRenderGroupListener]) * 13. OnAfterRenderEntryListeners are fired ([.addOnAfterRenderEntryListener]) */ @SysUISingleton class NotifPipeline @Inject constructor( private val mNotifCollection: NotifCollection, private val mShadeListBuilder: ShadeListBuilder private val mShadeListBuilder: ShadeListBuilder, private val mRenderStageManager: RenderStageManager ) : CommonNotifCollection { /** * Returns the list of all known notifications, i.e. the notifications that are currently posted Loading Loading @@ -205,6 +213,28 @@ class NotifPipeline @Inject constructor( mShadeListBuilder.addPreRenderInvalidator(invalidator) } /** * Called at the end of the pipeline after the notif list has been handed off to the view layer. */ fun addOnAfterRenderListListener(listener: OnAfterRenderListListener) { mRenderStageManager.addOnAfterRenderListListener(listener) } /** * Called at the end of the pipeline after a group has been handed off to the view layer. */ fun addOnAfterRenderGroupListener(listener: OnAfterRenderGroupListener) { mRenderStageManager.addOnAfterRenderGroupListener(listener) } /** * Called at the end of the pipeline after an entry has been handed off to the view layer. * This will be called for every top level entry, every group summary, and every group child. */ fun addOnAfterRenderEntryListener(listener: OnAfterRenderEntryListener) { mRenderStageManager.addOnAfterRenderEntryListener(listener) } /** * Get an object which can be used to update a notification (internally to the pipeline) * in response to a user action. Loading