Merge "Bouncer should dismiss if being tracked when face unlocked" into tm-d1-dev
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 c9d70d1..e2ed1d8 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
@@ -1323,10 +1323,24 @@
         if (mOnStackYChanged != null) {
             mOnStackYChanged.accept(listenerNeedsAnimation);
         }
+        updateStackEndHeightAndStackHeight(fraction);
+    }
+
+    @VisibleForTesting
+    public void updateStackEndHeightAndStackHeight(float fraction) {
+        final float oldStackHeight = mAmbientState.getStackHeight();
         if (mQsExpansionFraction <= 0 && !shouldSkipHeightUpdate()) {
             final float endHeight = updateStackEndHeight(
                     getHeight(), getEmptyBottomMargin(), mTopPadding);
             updateStackHeight(endHeight, fraction);
+        } else {
+            // Always updateStackHeight to prevent jumps in the stack height when this fraction
+            // suddenly reapplies after a freeze.
+            final float endHeight = mAmbientState.getStackEndHeight();
+            updateStackHeight(endHeight, fraction);
+        }
+        if (oldStackHeight != mAmbientState.getStackHeight()) {
+            requestChildrenUpdate();
         }
     }
 
@@ -1343,6 +1357,7 @@
         return stackEndHeight;
     }
 
+    @VisibleForTesting
     public void updateStackHeight(float endHeight, float fraction) {
         // During the (AOD<=>LS) transition where dozeAmount is changing,
         // apply dozeAmount to stack height instead of expansionFraction
@@ -5041,6 +5056,19 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void setUnlockHintRunning(boolean running) {
         mAmbientState.setUnlockHintRunning(running);
+        if (!running) {
+            // re-calculate the stack height which was frozen while running this animation
+            updateStackPosition();
+        }
+    }
+
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    public void setPanelFlinging(boolean flinging) {
+        mAmbientState.setIsFlinging(flinging);
+        if (!flinging) {
+            // re-calculate the stack height which was frozen while flinging
+            updateStackPosition();
+        }
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_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 2493ccb..010e6cf 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
@@ -1190,6 +1190,10 @@
         mView.setUnlockHintRunning(running);
     }
 
+    public void setPanelFlinging(boolean flinging) {
+        mView.setPanelFlinging(flinging);
+    }
+
     public boolean isFooterViewNotGone() {
         return mView.isFooterViewNotGone();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 2cac001..3580fe6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1782,14 +1782,14 @@
         mHeadsUpTouchHelper.notifyFling(!expand);
         mKeyguardStateController.notifyPanelFlingStart(!expand /* flingingToDismiss */);
         setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f);
-        mAmbientState.setIsFlinging(true);
+        mNotificationStackScrollLayoutController.setPanelFlinging(true);
         super.flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing);
     }
 
     @Override
     protected void onFlingEnd(boolean cancelled) {
         super.onFlingEnd(cancelled);
-        mAmbientState.setIsFlinging(false);
+        mNotificationStackScrollLayoutController.setPanelFlinging(false);
     }
 
     private boolean onQsIntercept(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 82ca842..5d417e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -599,9 +599,7 @@
             float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) {
         if (target == mExpandedHeight && mOverExpansion == 0.0f) {
             // We're at the target and didn't fling and there's no overshoot
-            endJankMonitoring(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
-            mKeyguardStateController.notifyPanelFlingEnd();
-            notifyExpandingFinished();
+            onFlingEnd(false /* cancelled */);
             return;
         }
         mIsFlinging = true;
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 f5fe6f3..b83743c 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
@@ -39,6 +39,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -122,12 +123,12 @@
         allowTestableLooperAsMainThread();
 
         // Interact with real instance of AmbientState.
-        mAmbientState = new AmbientState(
+        mAmbientState = spy(new AmbientState(
                 mContext,
                 mDumpManager,
                 mNotificationSectionsManager,
                 mBypassController,
-                mStatusBarKeyguardViewManager);
+                mStatusBarKeyguardViewManager));
 
         // Inject dependencies before initializing the layout
         mDependency.injectTestDependency(SysuiStatusBarStateController.class, mBarState);
@@ -190,7 +191,7 @@
                 endHeight, dozeAmount);
 
         mStackScroller.updateStackHeight(endHeight, expansionFraction);
-        assertTrue(mAmbientState.getStackHeight() == expected);
+        assertThat(mAmbientState.getStackHeight()).isEqualTo(expected);
     }
 
     @Test
@@ -205,7 +206,74 @@
                 endHeight, expansionFraction);
 
         mStackScroller.updateStackHeight(endHeight, expansionFraction);
-        assertTrue(mAmbientState.getStackHeight() == expected);
+        assertThat(mAmbientState.getStackHeight()).isEqualTo(expected);
+    }
+
+    @Test
+    public void updateStackEndHeightAndStackHeight_normallyUpdatesBoth() {
+        final float expansionFraction = 0.5f;
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+
+        // Validate that by default we update everything
+        clearInvocations(mAmbientState);
+        mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
+        verify(mAmbientState).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+    }
+
+    @Test
+    public void updateStackEndHeightAndStackHeight_onlyUpdatesStackHeightDuringSwipeUp() {
+        final float expansionFraction = 0.5f;
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+        mAmbientState.setSwipingUp(true);
+
+        // Validate that when the gesture is in progress, we update only the stackHeight
+        clearInvocations(mAmbientState);
+        mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
+        verify(mAmbientState, never()).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+    }
+
+    @Test
+    public void setPanelFlinging_updatesStackEndHeightOnlyOnFinish() {
+        final float expansionFraction = 0.5f;
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+        mAmbientState.setSwipingUp(true);
+        mStackScroller.setPanelFlinging(true);
+        mAmbientState.setSwipingUp(false);
+
+        // Validate that when the animation is running, we update only the stackHeight
+        clearInvocations(mAmbientState);
+        mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
+        verify(mAmbientState, never()).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+
+        // Validate that when the animation ends the stackEndHeight is recalculated immediately
+        clearInvocations(mAmbientState);
+        mStackScroller.setPanelFlinging(false);
+        verify(mAmbientState).setIsFlinging(eq(false));
+        verify(mAmbientState).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+    }
+
+    @Test
+    public void setUnlockHintRunning_updatesStackEndHeightOnlyOnFinish() {
+        final float expansionFraction = 0.5f;
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+        mStackScroller.setUnlockHintRunning(true);
+
+        // Validate that when the animation is running, we update only the stackHeight
+        clearInvocations(mAmbientState);
+        mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
+        verify(mAmbientState, never()).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+
+        // Validate that when the animation ends the stackEndHeight is recalculated immediately
+        clearInvocations(mAmbientState);
+        mStackScroller.setUnlockHintRunning(false);
+        verify(mAmbientState).setUnlockHintRunning(eq(false));
+        verify(mAmbientState).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index d47644f..8900d8f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -986,6 +986,21 @@
     }
 
     @Test
+    public void testSwipe_exactlyToTarget_notifiesNssl() {
+        // No over-expansion
+        mNotificationPanelViewController.setOverExpansion(0f);
+        // Fling to a target that is equal to the current position (i.e. a no-op fling).
+        mNotificationPanelViewController.flingToHeight(
+                0f,
+                true,
+                mNotificationPanelViewController.mExpandedHeight,
+                1f,
+                false);
+        // Verify that the NSSL is notified that the panel is *not* flinging.
+        verify(mNotificationStackScrollLayoutController).setPanelFlinging(false);
+    }
+
+    @Test
     public void testDoubleTapRequired_Keyguard() {
         FalsingManager.FalsingTapListener listener = getFalsingTapListener();
         mStatusBarStateController.setState(KEYGUARD);
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index c678a67..e1a0bfd 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -160,6 +160,7 @@
     public static final String[] AIDL_INTERFACE_PREFIXES_OF_INTEREST = new String[] {
             "android.hardware.biometrics.face.IFace/",
             "android.hardware.biometrics.fingerprint.IFingerprint/",
+            "android.hardware.input.processor.IInputProcessor/",
             "android.hardware.light.ILights/",
             "android.hardware.power.IPower/",
             "android.hardware.power.stats.IPowerStats/",