Merge changes Ic8f22359,I3b94dee1

* changes:
  Don't query settings for the notification history state every time we update the footer.
  Add trace sections for comparison of the notification pipelines
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 391525e..092e86d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -179,6 +179,7 @@
         if (!mNotifPipelineFlags.checkLegacyPipelineEnabled()) {
             return;
         }
+        Trace.beginSection("NotificationViewHierarchyManager.updateNotificationViews");
 
         beginUpdate();
 
@@ -353,6 +354,7 @@
         mListContainer.onNotificationViewUpdateFinished();
 
         endUpdate();
+        Trace.endSection();
     }
 
     /**
@@ -362,6 +364,7 @@
      * {@link com.android.systemui.statusbar.notification.collection.coordinator.StackCoordinator}
      */
     private void updateNotifStats() {
+        Trace.beginSection("NotificationViewHierarchyManager.updateNotifStats");
         boolean hasNonClearableAlertingNotifs = false;
         boolean hasClearableAlertingNotifs = false;
         boolean hasNonClearableSilentNotifs = false;
@@ -403,6 +406,7 @@
                 hasNonClearableSilentNotifs /* hasNonClearableSilentNotifs */,
                 hasClearableSilentNotifs /* hasClearableSilentNotifs */
         ));
+        Trace.endSection();
     }
 
     /**
@@ -520,7 +524,7 @@
     }
 
     private void updateRowStatesInternal() {
-        Trace.beginSection("NotificationViewHierarchyManager#updateRowStates");
+        Trace.beginSection("NotificationViewHierarchyManager.updateRowStates");
         final int N = mListContainer.getContainerChildCount();
 
         int visibleNotifications = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index c331608..ad9f12e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -24,6 +24,7 @@
 import android.app.NotificationChannel;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
@@ -343,11 +344,14 @@
     private final InflationCallback mInflationCallback = new InflationCallback() {
         @Override
         public void handleInflationException(NotificationEntry entry, Exception e) {
+            Trace.beginSection("NotificationEntryManager.handleInflationException");
             NotificationEntryManager.this.handleInflationException(entry.getSbn(), e);
+            Trace.endSection();
         }
 
         @Override
         public void onAsyncInflationFinished(NotificationEntry entry) {
+            Trace.beginSection("NotificationEntryManager.onAsyncInflationFinished");
             mPendingNotifications.remove(entry.getKey());
             // If there was an async task started after the removal, we don't want to add it back to
             // the list, otherwise we might get leaks.
@@ -369,6 +373,7 @@
                     }
                 }
             }
+            Trace.endSection();
         }
     };
 
@@ -463,6 +468,7 @@
             boolean forceRemove,
             DismissedByUserStats dismissedByUserStats,
             int reason) {
+        Trace.beginSection("NotificationEntryManager.removeNotificationInternal");
 
         final NotificationEntry entry = getActiveNotificationUnfiltered(key);
 
@@ -470,6 +476,7 @@
             if (interceptor.onNotificationRemoveRequested(key, entry, reason)) {
                 // Remove intercepted; log and skip
                 mLogger.logRemovalIntercepted(key);
+                Trace.endSection();
                 return;
             }
         }
@@ -557,6 +564,7 @@
                 mLeakDetector.trackGarbage(entry);
             }
         }
+        Trace.endSection();
     }
 
     private void sendNotificationRemovalToServer(
@@ -620,6 +628,7 @@
     private void addNotificationInternal(
             StatusBarNotification notification,
             RankingMap rankingMap) throws InflationException {
+        Trace.beginSection("NotificationEntryManager.addNotificationInternal");
         String key = notification.getKey();
         if (DEBUG) {
             Log.d(TAG, "addNotification key=" + key);
@@ -667,6 +676,7 @@
         for (NotifCollectionListener listener : mNotifCollectionListeners) {
             listener.onRankingApplied();
         }
+        Trace.endSection();
     }
 
     public void addNotification(StatusBarNotification notification, RankingMap ranking) {
@@ -679,12 +689,14 @@
 
     private void updateNotificationInternal(StatusBarNotification notification,
             RankingMap ranking) throws InflationException {
+        Trace.beginSection("NotificationEntryManager.updateNotificationInternal");
         if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
 
         final String key = notification.getKey();
         abortExistingInflation(key, "updateNotification");
         final NotificationEntry entry = getActiveNotificationUnfiltered(key);
         if (entry == null) {
+            Trace.endSection();
             return;
         }
 
@@ -721,6 +733,7 @@
         for (NotifCollectionListener listener : mNotifCollectionListeners) {
             listener.onRankingApplied();
         }
+        Trace.endSection();
     }
 
     public void updateNotification(StatusBarNotification notification, RankingMap ranking) {
@@ -740,14 +753,17 @@
             mLogger.logUseWhileNewPipelineActive("updateNotifications", reason);
             return;
         }
+        Trace.beginSection("NotificationEntryManager.updateNotifications");
         reapplyFilterAndSort(reason);
         if (mPresenter != null) {
             mPresenter.updateNotificationViews(reason);
         }
         mNotifLiveDataStore.setActiveNotifList(getVisibleNotifications());
+        Trace.endSection();
     }
 
     public void updateNotificationRanking(RankingMap rankingMap) {
+        Trace.beginSection("NotificationEntryManager.updateNotificationRanking");
         List<NotificationEntry> entries = new ArrayList<>();
         entries.addAll(getVisibleNotifications());
         entries.addAll(mPendingNotifications.values());
@@ -788,6 +804,7 @@
         for (NotifCollectionListener listener : mNotifCollectionListeners) {
             listener.onRankingApplied();
         }
+        Trace.endSection();
     }
 
     void notifyChannelModified(
@@ -887,6 +904,7 @@
 
     /** @return list of active notifications filtered for the current user */
     public List<NotificationEntry> getActiveNotificationsForCurrentUser() {
+        Trace.beginSection("NotificationEntryManager.getActiveNotificationsForCurrentUser");
         Assert.isMainThread();
         ArrayList<NotificationEntry> filtered = new ArrayList<>();
 
@@ -898,7 +916,7 @@
             }
             filtered.add(entry);
         }
-
+        Trace.endSection();
         return filtered;
     }
 
@@ -908,10 +926,12 @@
      * @param reason the reason for calling this method, which will be logged
      */
     public void updateRanking(RankingMap rankingMap, String reason) {
+        Trace.beginSection("NotificationEntryManager.updateRanking");
         updateRankingAndSort(rankingMap, reason);
         for (NotifCollectionListener listener : mNotifCollectionListeners) {
             listener.onRankingApplied();
         }
+        Trace.endSection();
     }
 
     /** Resorts / filters the current notification set with the current RankingMap */
@@ -920,7 +940,9 @@
             mLogger.logUseWhileNewPipelineActive("reapplyFilterAndSort", reason);
             return;
         }
+        Trace.beginSection("NotificationEntryManager.reapplyFilterAndSort");
         updateRankingAndSort(mRanker.getRankingMap(), reason);
+        Trace.endSection();
     }
 
     /** Calls to NotificationRankingManager and updates mSortedAndFiltered */
@@ -929,9 +951,11 @@
             mLogger.logUseWhileNewPipelineActive("updateRankingAndSort", reason);
             return;
         }
+        Trace.beginSection("NotificationEntryManager.updateRankingAndSort");
         mSortedAndFiltered.clear();
         mSortedAndFiltered.addAll(mRanker.updateRanking(
                 rankingMap, mActiveNotifications.values(), reason));
+        Trace.endSection();
     }
 
     /** dump the current active notification list. Called from StatusBar */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 74c97fd..31d9f09 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -426,14 +426,18 @@
         }
         Trace.endSection();
 
+        Trace.beginSection("ShadeListBuilder.logEndBuildList");
         // Step 9: We're done!
         mLogger.logEndBuildList(
                 mIterationCount,
                 mReadOnlyNotifList.size(),
                 countChildren(mReadOnlyNotifList));
         if (mAlwaysLogList || mIterationCount % 10 == 0) {
+            Trace.beginSection("ShadeListBuilder.logFinalList");
             mLogger.logFinalList(mNotifList);
+            Trace.endSection();
         }
+        Trace.endSection();
         mPipelineState.setState(STATE_IDLE);
         mIterationCount++;
         Trace.endSection();
@@ -996,16 +1000,20 @@
     }
 
     private void freeEmptyGroups() {
+        Trace.beginSection("ShadeListBuilder.freeEmptyGroups");
         mGroups.values().removeIf(ge -> ge.getSummary() == null && ge.getChildren().isEmpty());
+        Trace.endSection();
     }
 
     private void logChanges() {
+        Trace.beginSection("ShadeListBuilder.logChanges");
         for (NotificationEntry entry : mAllEntries) {
             logAttachStateChanges(entry);
         }
         for (GroupEntry group : mGroups.values()) {
             logAttachStateChanges(group);
         }
+        Trace.endSection();
     }
 
     private void logAttachStateChanges(ListEntry entry) {
@@ -1083,6 +1091,7 @@
     }
 
     private void cleanupPluggables() {
+        Trace.beginSection("ShadeListBuilder.cleanupPluggables");
         callOnCleanup(mNotifPreGroupFilters);
         callOnCleanup(mNotifPromoters);
         callOnCleanup(mNotifFinalizeFilters);
@@ -1093,6 +1102,7 @@
         }
 
         callOnCleanup(List.of(getStabilityManager()));
+        Trace.endSection();
     }
 
     private void callOnCleanup(List<? extends Pluggable<?>> pluggables) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
index c6a8a69..1c96e8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.statusbar.notification.collection.render.NotifStats
 import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
 import com.android.systemui.statusbar.phone.NotificationIconAreaController
+import com.android.systemui.util.traceSection
 import javax.inject.Inject
 
 /**
@@ -38,10 +39,11 @@
         pipeline.addOnAfterRenderListListener(::onAfterRenderList)
     }
 
-    fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) {
-        controller.setNotifStats(calculateNotifStats(entries))
-        notificationIconAreaController.updateNotificationIcons(entries)
-    }
+    fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) =
+        traceSection("StackCoordinator.onAfterRenderList") {
+            controller.setNotifStats(calculateNotifStats(entries))
+            notificationIconAreaController.updateNotificationIcons(entries)
+        }
 
     private fun calculateNotifStats(entries: List<ListEntry>): NotifStats {
         var hasNonClearableAlertingNotifs = false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index b02dc0c..54e26c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -39,6 +39,7 @@
 import com.android.systemui.util.children
 import com.android.systemui.util.foldToSparseArray
 import com.android.systemui.util.takeUntil
+import com.android.systemui.util.traceSection
 import javax.inject.Inject
 
 /**
@@ -157,7 +158,9 @@
             }
         }
     }
-    private fun logShadeContents() = parent.children.forEachIndexed(::logShadeChild)
+    private fun logShadeContents() = traceSection("NotifSectionsManager.logShadeContents") {
+        parent.children.forEachIndexed(::logShadeChild)
+    }
 
     private val isUsingMultipleSections: Boolean
         get() = sectionsFeatureManager.getNumberOfBuckets() > 1
@@ -221,10 +224,10 @@
      * Should be called whenever notifs are added, removed, or updated. Updates section boundary
      * bookkeeping and adds/moves/removes section headers if appropriate.
      */
-    fun updateSectionBoundaries(reason: String) {
+    fun updateSectionBoundaries(reason: String) = traceSection("NotifSectionsManager.update") {
         notifPipelineFlags.checkLegacyPipelineEnabled()
         if (!isUsingMultipleSections) {
-            return
+            return@traceSection
         }
         logger.logStartSectionUpdate(reason)
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index dd72615..25b8a65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -43,7 +43,6 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.IndentingPrintWriter;
@@ -696,8 +695,7 @@
                 && mQsExpansionFraction != 1
                 && !mScreenOffAnimationController.shouldHideNotificationsFooter()
                 && !mIsRemoteInputActive;
-        boolean showHistory = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, UserHandle.USER_CURRENT) == 1;
+        boolean showHistory = mController.isHistoryEnabled();
 
         updateFooterView(showFooterView, showDismissView, showHistory);
     }
@@ -5243,11 +5241,10 @@
                 R.layout.status_bar_no_notifications, this, false);
         view.setText(R.string.empty_shade_text);
         view.setOnClickListener(v -> {
-            final boolean showHistory = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, UserHandle.USER_CURRENT) == 1;
-            Intent intent = showHistory ? new Intent(
-                    Settings.ACTION_NOTIFICATION_HISTORY) : new Intent(
-                    Settings.ACTION_NOTIFICATION_SETTINGS);
+            final boolean showHistory = mController.isHistoryEnabled();
+            Intent intent = showHistory
+                    ? new Intent(Settings.ACTION_NOTIFICATION_HISTORY)
+                    : new Intent(Settings.ACTION_NOTIFICATION_SETTINGS);
             mStatusBar.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
         });
         setEmptyShadeView(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 334128a..a2929f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -35,6 +35,8 @@
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.PointF;
+import android.os.Trace;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
@@ -180,7 +182,6 @@
     private final NotificationLockscreenUserManager mLockscreenUserManager;
     // TODO: StatusBar should be encapsulated behind a Controller
     private final StatusBar mStatusBar;
-    private final NotificationGroupManagerLegacy mLegacyGroupManager;
     private final SectionHeaderController mSilentHeaderController;
     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
     private final InteractionJankMonitor mJankMonitor;
@@ -191,6 +192,7 @@
     private boolean mFadeNotificationsOnDismiss;
     private NotificationSwipeHelper mSwipeHelper;
     private boolean mShowEmptyShadeView;
+    @Nullable private Boolean mHistoryEnabled;
     private int mBarState;
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
 
@@ -340,6 +342,8 @@
         @Override
         public void onUserChanged(int userId) {
             mView.updateSensitiveness(false, mLockscreenUserManager.isAnyProfilePublicMode());
+            mHistoryEnabled = null;
+            updateFooter();
         }
     };
 
@@ -699,8 +703,6 @@
             }
         });
         mNotifPipelineFlags = notifPipelineFlags;
-        mLegacyGroupManager = mNotifPipelineFlags.isNewPipelineEnabled()
-                ? null : legacyGroupManager;
         mSilentHeaderController = silentHeaderController;
         mNotifPipeline = notifPipeline;
         mNotifCollection = notifCollection;
@@ -802,6 +804,7 @@
                 (key, newValue) -> {
                     switch (key) {
                         case Settings.Secure.NOTIFICATION_HISTORY_ENABLED:
+                            mHistoryEnabled = null;  // invalidate
                             updateFooter();
                             break;
                         case HIGH_PRIORITY:
@@ -1009,6 +1012,20 @@
         return mNotifStats.getNumActiveNotifs();
     }
 
+    public boolean isHistoryEnabled() {
+        Boolean historyEnabled = mHistoryEnabled;
+        if (historyEnabled == null) {
+            if (mView == null || mView.getContext() == null) {
+                Log.wtf(TAG, "isHistoryEnabled failed to initialize its value");
+                return false;
+            }
+            mHistoryEnabled = historyEnabled =
+                    Settings.Secure.getIntForUser(mView.getContext().getContentResolver(),
+                    Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, UserHandle.USER_CURRENT) == 1;
+        }
+        return historyEnabled;
+    }
+
     public int getIntrinsicContentHeight() {
         return mView.getIntrinsicContentHeight();
     }
@@ -1199,6 +1216,7 @@
      * are true.
      */
     public void updateShowEmptyShadeView() {
+        Trace.beginSection("NSSLC.updateShowEmptyShadeView");
         mShowEmptyShadeView = mBarState != KEYGUARD
                 && (!mView.isQsExpanded() || mView.isUsingSplitNotificationShade())
                 && getVisibleNotificationCount() == 0;
@@ -1206,6 +1224,7 @@
         mView.updateEmptyShadeView(
                 mShowEmptyShadeView,
                 mZenModeController.areNotificationsHiddenInShade());
+        Trace.endSection();
     }
 
     public boolean areNotificationsHiddenInShade() {
@@ -1323,11 +1342,15 @@
         if (mNotifPipelineFlags.isNewPipelineEnabled()) {
             return;
         }
+        Trace.beginSection("NSSLC.updateSectionBoundaries");
         mView.updateSectionBoundaries(reason);
+        Trace.endSection();
     }
 
     public void updateFooter() {
+        Trace.beginSection("NSSLC.updateFooter");
         mView.updateFooter();
+        Trace.endSection();
     }
 
     public void onUpdateRowStates() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index bdcbbbc..4f731ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.notification.stack;
 
-import static android.provider.Settings.Secure.NOTIFICATION_HISTORY_ENABLED;
 import static android.view.View.GONE;
 
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
@@ -41,8 +40,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.os.UserHandle;
-import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.MathUtils;
@@ -112,10 +109,6 @@
     public void setUp() throws Exception {
         allowTestableLooperAsMainThread();
 
-        Settings.Secure.putIntForUser(mContext.getContentResolver(), NOTIFICATION_HISTORY_ENABLED,
-                1, UserHandle.USER_CURRENT);
-
-
         // Interact with real instance of AmbientState.
         mAmbientState = new AmbientState(mContext, mNotificationSectionsManager, mBypassController);
 
@@ -150,6 +143,7 @@
         mStackScroller.setShelfController(notificationShelfController);
         mStackScroller.setStatusBar(mBar);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
+        when(mStackScrollLayoutController.isHistoryEnabled()).thenReturn(true);
         when(mStackScrollLayoutController.getNoticationRoundessManager())
                 .thenReturn(mNotificationRoundnessManager);
         mStackScroller.setController(mStackScrollLayoutController);
@@ -404,6 +398,22 @@
     }
 
     @Test
+    public void testUpdateFooter_withoutHistory() {
+        setBarStateForTest(StatusBarState.SHADE);
+        mStackScroller.setCurrentUserSetup(true);
+
+        when(mStackScrollLayoutController.isHistoryEnabled()).thenReturn(false);
+        when(mStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(1);
+        when(mStackScrollLayoutController.hasActiveClearableNotifications(eq(ROWS_ALL)))
+                .thenReturn(true);
+
+        FooterView view = mock(FooterView.class);
+        mStackScroller.setFooterView(view);
+        mStackScroller.updateFooter();
+        verify(mStackScroller).updateFooterView(true, true, false);
+    }
+
+    @Test
     public void testUpdateFooter_oneClearableNotification_beforeUserSetup() {
         setBarStateForTest(StatusBarState.SHADE);
         mStackScroller.setCurrentUserSetup(false);