Merge "Add padlock to the top of the bouncer"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_message_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_message_area.xml
index e1bf6cb..5da7611 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_message_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_message_area.xml
@@ -17,15 +17,24 @@
 */
 -->
 
-<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
-<com.android.keyguard.KeyguardMessageArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    style="@style/Keyguard.TextView"
-    android:id="@+id/keyguard_message_area"
-    android:singleLine="true"
-    android:ellipsize="marquee"
-    android:focusable="true" />
-
+<!-- This contains error message field and padlock shared by pin/pattern/password screens -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content" >
+    <FrameLayout
+        android:id="@+id/lock_icon_container"
+        android:layout_gravity="center"
+        android:layout_marginBottom="@dimen/keyguard_lock_padding"
+        android:layout_width="@dimen/keyguard_lock_width"
+        android:layout_height="@dimen/keyguard_lock_height" />
+    <com.android.keyguard.KeyguardMessageArea
+        android:id="@+id/keyguard_message_area"
+        style="@style/Keyguard.TextView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:focusable="true" />
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/values-sw320dp/dimens.xml b/packages/SystemUI/res-keyguard/values-sw320dp/dimens.xml
index 38d2ecc3..91ca5c5 100644
--- a/packages/SystemUI/res-keyguard/values-sw320dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-sw320dp/dimens.xml
@@ -21,6 +21,6 @@
 
     <!-- Height of the sliding KeyguardSecurityContainer
          (includes 2x keyguard_security_view_top_margin) -->
-    <dimen name="keyguard_security_height">345dp</dimen>
+    <dimen name="keyguard_security_height">395dp</dimen>
 
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sw360dp/dimens.xml b/packages/SystemUI/res-keyguard/values-sw360dp/dimens.xml
index 90c4795..d7c9975 100644
--- a/packages/SystemUI/res-keyguard/values-sw360dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-sw360dp/dimens.xml
@@ -21,5 +21,5 @@
 
     <!-- Height of the sliding KeyguardSecurityContainer (includes 2x
          keyguard_security_view_top_margin) -->
-    <dimen name="keyguard_security_height">400dp</dimen>
+    <dimen name="keyguard_security_height">450dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sw540dp-port/dimens.xml b/packages/SystemUI/res-keyguard/values-sw540dp-port/dimens.xml
index 9ea04dc..a3c37e4 100644
--- a/packages/SystemUI/res-keyguard/values-sw540dp-port/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-sw540dp-port/dimens.xml
@@ -20,5 +20,5 @@
 <resources>
     <!-- Height of the sliding KeyguardSecurityContainer
         (includes 2x keyguard_security_view_top_margin) -->
-    <dimen name="keyguard_security_height">500dp</dimen>
+    <dimen name="keyguard_security_height">550dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sw720dp/dimens.xml b/packages/SystemUI/res-keyguard/values-sw720dp/dimens.xml
index 9157822..1dc61c5 100644
--- a/packages/SystemUI/res-keyguard/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-sw720dp/dimens.xml
@@ -20,7 +20,7 @@
 
     <!-- Height of the sliding KeyguardSecurityContainer
          (includes 2x keyguard_security_view_top_margin) -->
-    <dimen name="keyguard_security_height">420dp</dimen>
+    <dimen name="keyguard_security_height">470dp</dimen>
 
     <dimen name="widget_big_font_size">100dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index b6a41c1..d67c98a 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -27,11 +27,11 @@
 
     <!-- Height of the sliding KeyguardSecurityContainer
          (includes 2x keyguard_security_view_top_margin) -->
-    <dimen name="keyguard_security_height">400dp</dimen>
+    <dimen name="keyguard_security_height">450dp</dimen>
 
     <!-- Max Height of the sliding KeyguardSecurityContainer
          (includes 2x keyguard_security_view_top_margin) -->
-    <dimen name="keyguard_security_max_height">455dp</dimen>
+    <dimen name="keyguard_security_max_height">505dp</dimen>
 
     <!-- Margin around the various security views -->
     <dimen name="keyguard_security_view_top_margin">8dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 0a39549..2da6824 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -492,13 +492,10 @@
             int currentAlpha = getImageAlpha();
             ValueAnimator animator = ValueAnimator.ofInt(currentAlpha, endAlpha);
             mAlphaAnimator = animator;
-            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator animation) {
-                    int alpha = (int) animation.getAnimatedValue();
-                    if (background != null) background.mutate().setAlpha(alpha);
-                    setImageAlpha(alpha);
-                }
+            animator.addUpdateListener(animation -> {
+                int alpha1 = (int) animation.getAnimatedValue();
+                if (background != null) background.mutate().setAlpha(alpha1);
+                setImageAlpha(alpha1);
             });
             animator.addListener(mAlphaEndListener);
             if (interpolator == null) {
@@ -520,6 +517,10 @@
         }
     }
 
+    public boolean isAnimatingAlpha() {
+        return mAlphaAnimator != null;
+    }
+
     private Animator.AnimatorListener getEndListener(final Runnable runnable) {
         return new AnimatorListenerAdapter() {
             boolean mCancelled;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 6fe23fb..847f3ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -831,6 +831,15 @@
         }
     }
 
+    /**
+     * Sets the alpha of the indication areas and affordances, excluding the lock icon.
+     */
+    public void setAffordanceAlpha(float alpha) {
+        mLeftAffordanceView.setAlpha(alpha);
+        mRightAffordanceView.setAlpha(alpha);
+        mIndicationArea.setAlpha(alpha);
+    }
+
     private class DefaultLeftButton implements IntentButton {
 
         private IconState mIconState = new IconState();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 7d13679..19373ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -88,6 +88,7 @@
     private int mBouncerPromptReason;
     private boolean mIsAnimatingAway;
     private boolean mIsScrimmed;
+    private ViewGroup mLockIconContainer;
 
     public KeyguardBouncer(Context context, ViewMediatorCallback callback,
             LockPatternUtils lockPatternUtils, ViewGroup container,
@@ -171,6 +172,10 @@
         return isShowing() && mIsScrimmed;
     }
 
+    public ViewGroup getLockIconContainer() {
+        return mRoot == null || mRoot.getVisibility() != View.VISIBLE ? null : mLockIconContainer;
+    }
+
     /**
      * This method must be called at the end of the bouncer animation when
      * the translation is performed manually by the user, otherwise FalsingManager
@@ -401,6 +406,7 @@
         removeView();
         mHandler.removeCallbacks(mRemoveViewRunnable);
         mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null);
+        mLockIconContainer = mRoot.findViewById(R.id.lock_icon_container);
         mKeyguardView = mRoot.findViewById(R.id.keyguard_host_view);
         mKeyguardView.setLockPatternUtils(mLockPatternUtils);
         mKeyguardView.setViewMediatorCallback(mCallback);
@@ -420,6 +426,7 @@
         if (mRoot != null && mRoot.getParent() == mContainer) {
             mContainer.removeView(mRoot);
             mRoot = null;
+            mLockIconContainer = null;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index babee53..253bdfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -192,7 +192,6 @@
     protected int mQsMinExpansionHeight;
     protected int mQsMaxExpansionHeight;
     private int mQsPeekHeight;
-    private int mBouncerTop;
     private boolean mStackScrollerOverscrolling;
     private boolean mQsExpansionFromOverscroll;
     private float mLastOverscroll;
@@ -325,6 +324,7 @@
     private final ShadeController mShadeController =
             Dependency.get(ShadeController.class);
     private int mDisplayId;
+    private KeyguardBouncer mBouncer;
 
     /**
      * Cache the resource id of the theme to avoid unnecessary work in onThemeChanged.
@@ -690,11 +690,6 @@
         return count;
     }
 
-    public void setBouncerTop(int bouncerTop) {
-        mBouncerTop = bouncerTop;
-        positionClockAndNotifications();
-    }
-
     private void updateClock() {
         if (!mKeyguardStatusViewAnimating) {
             mKeyguardStatusView.setAlpha(mClockPositionResult.clockAlpha);
@@ -1741,7 +1736,6 @@
         }
         updateExpandedHeight(expandedHeight);
         updateHeader();
-        updateUnlockIcon();
         updateNotificationTranslucency();
         updatePanelExpanded();
         if (DEBUG) {
@@ -1834,19 +1828,6 @@
         return mNotificationStackScroller.getCurrentOverScrolledPixels(true /* top */);
     }
 
-    private void updateUnlockIcon() {
-        if (mBarState == StatusBarState.KEYGUARD
-                || mBarState == StatusBarState.SHADE_LOCKED) {
-            boolean active = getMaxPanelHeight() - getExpandedHeight() > mUnlockMoveDistance;
-            KeyguardAffordanceView lockIcon = mKeyguardBottomArea.getLockIcon();
-            if (active != mUnlockIconActive && mTracking) {
-                lockIcon.setImageAlpha(lockIcon.getRestingAlpha(), true, 150,
-                        Interpolators.FAST_OUT_LINEAR_IN, null);
-            }
-            mUnlockIconActive = active;
-        }
-    }
-
     /**
      * Hides the header when notifications are colliding with it.
      */
@@ -1913,7 +1894,7 @@
                         ? 0 : KeyguardBouncer.ALPHA_EXPANSION_THRESHOLD, 1f,
                 0f, 1f, getExpandedFraction());
         float alpha = Math.min(expansionAlpha, 1 - getQsExpansionFraction());
-        mKeyguardBottomArea.setAlpha(alpha);
+        mKeyguardBottomArea.setAffordanceAlpha(alpha);
         mKeyguardBottomArea.setImportantForAccessibility(alpha == 0f
                 ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
                 : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
@@ -2061,11 +2042,6 @@
                 mAffordanceHelper.reset(true);
             }
         }
-        if (!expand && (mBarState == StatusBarState.KEYGUARD
-                || mBarState == StatusBarState.SHADE_LOCKED)) {
-            KeyguardAffordanceView lockIcon = mKeyguardBottomArea.getLockIcon();
-            lockIcon.setImageAlpha(0.0f, true, 100, Interpolators.FAST_OUT_LINEAR_IN, null);
-        }
     }
 
     @Override
@@ -2215,22 +2191,6 @@
             return;
         }
         super.startUnlockHintAnimation();
-        startHighlightIconAnimation(getCenterIcon());
-    }
-
-    /**
-     * Starts the highlight (making it fully opaque) animation on an icon.
-     */
-    private void startHighlightIconAnimation(final KeyguardAffordanceView icon) {
-        icon.setImageAlpha(1.0f, true, KeyguardAffordanceHelper.HINT_PHASE1_DURATION,
-                Interpolators.FAST_OUT_SLOW_IN, new Runnable() {
-                    @Override
-                    public void run() {
-                        icon.setImageAlpha(icon.getRestingAlpha(),
-                                true /* animate */, KeyguardAffordanceHelper.HINT_PHASE1_DURATION,
-                                Interpolators.FAST_OUT_SLOW_IN, null);
-                    }
-                });
     }
 
     @Override
@@ -2969,6 +2929,7 @@
     public void onBouncerPreHideAnimation() {
         setKeyguardStatusViewVisibility(mBarState, true /* keyguardFadingAway */,
                 false /* goingToFullShade */);
+        updateLockIcon();
     }
 
     @Override
@@ -3058,4 +3019,54 @@
     public void showTransientIndication(int id) {
         mKeyguardBottomArea.showTransientIndication(id);
     }
+
+    /**
+     * Sets the reference to the {@link KeyguardBouncer}.
+     */
+    public void setBouncer(KeyguardBouncer bouncer) {
+        mBouncer = bouncer;
+        updateLockIcon();
+    }
+
+    public void updateLockIcon() {
+        if (mBouncer == null) {
+            return;
+        }
+
+        ViewGroup bouncerContainer = mBouncer.getLockIconContainer();
+        LockIcon lockIcon = mKeyguardBottomArea.getLockIcon();
+
+        if (mBouncer.isAnimatingAway()) {
+            if (!lockIcon.isAnimatingAlpha() && lockIcon.getAlpha() != 0) {
+                lockIcon.setImageAlpha(0, true /* animate */);
+            }
+            // Let's not re-apply the translation if the bouncer is animating, its
+            // animation also includes translation and transition would be jarring.
+            return;
+        }
+
+        float translation = 0;
+        if (bouncerContainer != null) {
+            float bottomAreaContainerY = getCommonTop(lockIcon);
+            float bouncerLockY = getCommonTop(bouncerContainer);
+            if (bouncerLockY < bottomAreaContainerY) {
+                translation = bouncerLockY - bottomAreaContainerY;
+            }
+        }
+        lockIcon.setTranslationY(translation);
+
+        if (lockIcon.getAlpha() != 1) {
+            lockIcon.setImageAlpha(1, false /* animate */);
+        }
+    }
+
+    private static float getCommonTop(View view) {
+        float y = view.getTop();
+        ViewGroup parent = (ViewGroup) view.getParent();
+        while (!(parent instanceof StatusBarWindowView)) {
+            y += parent.getY();
+            parent = (ViewGroup) parent.getParent();
+        }
+        return y;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 2495d22..99345d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -1115,6 +1115,7 @@
 
         View[] viewsToAnimate = {
                 mKeyguardBottomArea.getIndicationArea(),
+                mKeyguardBottomArea.getLockIcon(),
                 mStatusBar.getAmbientIndicationContainer()};
         for (View v : viewsToAnimate) {
             if (v == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 8db0822..7e330e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -882,7 +882,6 @@
                         mNotificationPanel.getLockIcon());
         mNotificationPanel.setKeyguardIndicationController(mKeyguardIndicationController);
 
-
         mAmbientIndicationContainer = mStatusBarWindow.findViewById(
                 R.id.ambient_indication_container);
 
@@ -1220,6 +1219,7 @@
         mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
         mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
         mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
+        mNotificationPanel.setBouncer(mStatusBarKeyguardViewManager.getBouncer());
         Dependency.get(KeyguardDismissUtil.class).setDismissHandler(this::executeWhenUnlocked);
         Trace.endSection();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 5014783..e8a5c7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -166,16 +166,10 @@
         mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext,
                 mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry,
                 mExpansionCallback);
-        mContainer.addOnLayoutChangeListener(this::onContainerLayout);
         mNotificationPanelView = notificationPanelView;
         notificationPanelView.setExpansionListener(this::onPanelExpansionChanged);
     }
 
-    private void onContainerLayout(View v, int left, int top, int right, int bottom,
-            int oldLeft, int oldTop, int oldRight, int oldBottom) {
-        mNotificationPanelView.setBouncerTop(mBouncer.getTop());
-    }
-
     @VisibleForTesting
     void onPanelExpansionChanged(float expansion, boolean tracking) {
         // We don't want to translate the bounce when:
@@ -198,6 +192,7 @@
                 mBouncer.show(false /* resetSecuritySelection */, false /* scrimmed */);
             }
         }
+        mNotificationPanelView.updateLockIcon();
     }
 
     /**
@@ -795,6 +790,10 @@
         setDozing(isDozing);
     }
 
+    public KeyguardBouncer getBouncer() {
+        return mBouncer;
+    }
+
     private static class DismissWithActionRequest {
         final OnDismissAction dismissAction;
         final Runnable cancelAction;