Merge "Fix process source propagation for binder calls stats settings so that it is correctly reported in the pushed atom BinderLatencyReported." into sc-dev
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 7757b91f..6ce7cea 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -220,7 +220,8 @@
     public CallSession callStarted(Binder binder, int code, int workSourceUid) {
         noteNativeThreadId();
 
-        if (!canCollect()) {
+        // We always want to collect data for latency if it's enabled, regardless of device state.
+        if (!mCollectLatencyData && !canCollect()) {
             return null;
         }
 
@@ -267,6 +268,11 @@
             mLatencyObserver.callEnded(s);
         }
 
+        // Latency collection has already been processed so check if the rest should be processed.
+        if (!canCollect()) {
+            return;
+        }
+
         UidEntry uidEntry = null;
         final boolean recordCall;
         if (s.recordedCall) {
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index c502f75..82b2bf4 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -969,6 +970,22 @@
     }
 
     @Test
+    public void testLatencyCollectionActiveEvenWithoutDeviceState() {
+        TestBinderCallsStats bcs = new TestBinderCallsStats(null);
+        bcs.setCollectLatencyData(true);
+
+        Binder binder = new Binder();
+        CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
+        assertNotEquals(null, callSession);
+
+        bcs.time += 10;
+        bcs.elapsedTime += 20;
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+
+        assertEquals(1, bcs.getLatencyObserver().getLatencyHistograms().size());
+    }
+
+    @Test
     public void testLatencyCollectionEnabledByDefault() {
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         assertEquals(true, bcs.getCollectLatencyData());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 3c549f9..467f27f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -158,14 +158,7 @@
         final int N = activeNotifications.size();
         for (int i = 0; i < N; i++) {
             NotificationEntry ent = activeNotifications.get(i);
-            final boolean isBubbleNotificationSuppressedFromShade = mBubblesOptional.isPresent()
-                    && mBubblesOptional.get().isBubbleNotificationSuppressedFromShade(
-                            ent.getKey(), ent.getSbn().getGroupKey());
-            if (ent.isRowDismissed() || ent.isRowRemoved()
-                    || isBubbleNotificationSuppressedFromShade
-                    || mFgsSectionController.hasEntry(ent)) {
-                // we don't want to update removed notifications because they could
-                // temporarily become children if they were isolated before.
+            if (shouldSuppressActiveNotification(ent)) {
                 continue;
             }
 
@@ -254,9 +247,11 @@
         }
 
         for (ExpandableNotificationRow viewToRemove : viewsToRemove) {
-            if (mEntryManager.getPendingOrActiveNotif(viewToRemove.getEntry().getKey()) != null) {
+            NotificationEntry entry = viewToRemove.getEntry();
+            if (mEntryManager.getPendingOrActiveNotif(entry.getKey()) != null
+                && !shouldSuppressActiveNotification(entry)) {
                 // we are only transferring this notification to its parent, don't generate an
-                // animation
+                // animation. If the notification is suppressed, this isn't a transfer.
                 mListContainer.setChildTransferInProgress(true);
             }
             if (viewToRemove.isSummaryWithChildren()) {
@@ -325,6 +320,23 @@
         endUpdate();
     }
 
+    /**
+     * Should a notification entry from the active list be suppressed and not show?
+     */
+    private boolean shouldSuppressActiveNotification(NotificationEntry ent) {
+        final boolean isBubbleNotificationSuppressedFromShade = mBubblesOptional.isPresent()
+                && mBubblesOptional.get().isBubbleNotificationSuppressedFromShade(
+                        ent.getKey(), ent.getSbn().getGroupKey());
+        if (ent.isRowDismissed() || ent.isRowRemoved()
+                || isBubbleNotificationSuppressedFromShade
+                || mFgsSectionController.hasEntry(ent)) {
+            // we want to suppress removed notifications because they could
+            // temporarily become children if they were isolated before.
+            return true;
+        }
+        return false;
+    }
+
     private void addNotificationChildrenAndSort() {
         // Let's now add all notification children which are missing
         boolean orderChanged = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
index 924eb26..b6aed23 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
@@ -132,6 +132,8 @@
     public void removeRemoteInput(NotificationEntry entry, Object token) {
         Objects.requireNonNull(entry);
         if (entry.mRemoteEditImeVisible) return;
+        // If the view is being removed, this may be called even though we're not active
+        if (!isRemoteInputActive(entry)) return;
 
         pruneWeakThenRemoveAndContains(null /* contains */, entry /* remove */, token);
 
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 4e6d376..5ccb064 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
@@ -143,7 +143,7 @@
             false /* default */);
     // TODO(b/187291379) disable again before release
     private static final boolean DEBUG_REMOVE_ANIMATION = SystemProperties.getBoolean(
-            "persist.debug.nssl.dismiss", true /* default */);
+            "persist.debug.nssl.dismiss", false /* default */);
 
     private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
     private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f;
@@ -3205,6 +3205,13 @@
                     ignoreChildren);
             mAnimationEvents.add(event);
             mSwipedOutViews.remove(child);
+            if (DEBUG_REMOVE_ANIMATION) {
+                String key = "";
+                if (child instanceof ExpandableNotificationRow) {
+                    key = ((ExpandableNotificationRow) child).getEntry().getKey();
+                }
+                Log.d(TAG, "created Remove Event - SwipedOut: " + childWasSwipedOut + " " + key);
+            }
         }
         mChildrenToRemoveAnimated.clear();
     }