From 416493bf66dff0aa7fcd9ea505ed10dbff1f2906 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Sat, 13 Sep 2014 03:57:32 +0200 Subject: [PATCH] Fix jank while unlocking and security is set - Delay showing the bouncer and playing the entrance animation for a couple of frames. - Do not disable back button on the normal Keyguard. This makes the entrance animation nicer and fixes some jank due to the need to draw into both windows. - Prevent setPadding(...) call when nothing changes. setPadding would invalidate the padding for the whole view hierarchy, which results in a slower measure() when setting the window to invisible. Bug: 17419960 Change-Id: I4a239d4af40ad86875e4a0dd08473f19a5c9b961 --- .../statusbar/phone/KeyguardBouncer.java | 29 ++++++++++++++++--- .../statusbar/phone/NavigationBarView.java | 11 ++++++- .../statusbar/phone/PhoneStatusBar.java | 6 ++-- .../phone/StatusBarKeyguardViewManager.java | 28 ++++++++++++++++-- .../statusbar/phone/StatusBarWindowView.java | 16 ++++++++-- 5 files changed, 79 insertions(+), 11 deletions(-) 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 70b6952b1300a..5507944740c3b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone; import android.content.Context; +import android.view.Choreographer; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; @@ -43,7 +44,8 @@ public class KeyguardBouncer { private StatusBarWindowManager mWindowManager; private KeyguardViewBase mKeyguardView; private ViewGroup mRoot; - private boolean mFadingOut; + private boolean mShowingSoon; + private Choreographer mChoreographer = Choreographer.getInstance(); public KeyguardBouncer(Context context, ViewMediatorCallback callback, LockPatternUtils lockPatternUtils, StatusBarWindowManager windowManager, @@ -57,7 +59,7 @@ public class KeyguardBouncer { public void show() { ensureView(); - if (mRoot.getVisibility() == View.VISIBLE) { + if (mRoot.getVisibility() == View.VISIBLE || mShowingSoon) { // show() updates the current security method. This is needed in case we are already // showing and the current security method changed. @@ -68,10 +70,27 @@ public class KeyguardBouncer { // Try to dismiss the Keyguard. If no security pattern is set, this will dismiss the whole // Keyguard. If we need to authenticate, show the bouncer. if (!mKeyguardView.dismiss()) { + mShowingSoon = true; + + // Split up the work over multiple frames. + mChoreographer.postCallbackDelayed(Choreographer.CALLBACK_ANIMATION, mShowRunnable, + null, 48); + } + } + + private final Runnable mShowRunnable = new Runnable() { + @Override + public void run() { mRoot.setVisibility(View.VISIBLE); mKeyguardView.onResume(); mKeyguardView.startAppearAnimation(); + mShowingSoon = false; } + }; + + private void cancelShowRunnable() { + mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mShowRunnable, null); + mShowingSoon = false; } public void showWithDismissAction(OnDismissAction r) { @@ -81,7 +100,8 @@ public class KeyguardBouncer { } public void hide(boolean destroyView) { - if (mKeyguardView != null) { + cancelShowRunnable(); + if (mKeyguardView != null) { mKeyguardView.setOnDismissAction(null); mKeyguardView.cleanUp(); } @@ -107,6 +127,7 @@ public class KeyguardBouncer { * Reset the state of the view. */ public void reset() { + cancelShowRunnable(); inflateView(); } @@ -127,7 +148,7 @@ public class KeyguardBouncer { } public boolean isShowing() { - return mRoot != null && mRoot.getVisibility() == View.VISIBLE && !mFadingOut; + return mShowingSoon || (mRoot != null && mRoot.getVisibility() == View.VISIBLE); } public void prepare() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 0fb219259d67c..e0319f02eb7f2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -507,7 +507,16 @@ public class NavigationBarView extends LinearLayout { } } - + @Override + public void setVisibility(int visibility) { + super.setVisibility(visibility); + boolean visible = visibility == View.VISIBLE; + getBackButton().getBackground().setVisible(visible, false /* restart */); + getHomeButton().getBackground().setVisible(visible, false /* restart */); + getRecentsButton().getBackground().setVisible(visible, false /* restart */); + getMenuButton().getBackground().setVisible(visible, false /* restart */); + getImeSwitchButton().getBackground().setVisible(visible, false /* restart */); + } /* @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index e6db2c8c2f66f..5f582bba4c779 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -2364,8 +2364,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStackScroller.setVisibility(View.VISIBLE); mNotificationPanel.setVisibility(View.GONE); - setAreThereNotifications(); // show the clear button - mNotificationPanel.closeQs(); mExpandedVisible = false; @@ -3580,6 +3578,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, disable(mDisabledUnmodified, true /* animate */); } + public boolean isKeyguardFadingAway() { + return mKeyguardFadingAway; + } + /** * Notifies that the Keyguard fading away animation is done. */ 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 b4e2d57f8bd41..55c861a66ace5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -43,6 +43,10 @@ public class StatusBarKeyguardViewManager { // When hiding the Keyguard with timing supplied from WindowManager, better be early than late. private static final long HIDE_TIMING_CORRECTION_MS = -3 * 16; + // Delay for showing the navigation bar when the bouncer appears. This should be kept in sync + // with the appear animations of the PIN/pattern/password views. + private static final long NAV_BAR_SHOW_DELAY_BOUNCER = 320; + private static String TAG = "StatusBarKeyguardViewManager"; private final Context mContext; @@ -323,12 +327,30 @@ public class StatusBarKeyguardViewManager { return mBouncer.isShowing(); } + private long getNavBarShowDelay() { + if (mPhoneStatusBar.isKeyguardFadingAway()) { + return mPhoneStatusBar.getKeyguardFadingAwayDelay(); + } else { + + // Keyguard is not going away, thus we are showing the navigation bar because the + // bouncer is appearing. + return NAV_BAR_SHOW_DELAY_BOUNCER; + } + } + + private Runnable mMakeNavigationBarVisibleRunnable = new Runnable() { + @Override + public void run() { + mPhoneStatusBar.getNavigationBarView().setVisibility(View.VISIBLE); + } + }; + private void updateStates() { int vis = mContainer.getSystemUiVisibility(); boolean showing = mShowing; boolean occluded = mOccluded; boolean bouncerShowing = mBouncer.isShowing(); - boolean bouncerDismissible = bouncerShowing && !mBouncer.needsFullscreenBouncer(); + boolean bouncerDismissible = !mBouncer.needsFullscreenBouncer(); if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing) || mFirstUpdate) { @@ -342,8 +364,10 @@ public class StatusBarKeyguardViewManager { != (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing) || mFirstUpdate) { if (mPhoneStatusBar.getNavigationBarView() != null) { if (!(showing && !occluded) || bouncerShowing) { - mPhoneStatusBar.getNavigationBarView().setVisibility(View.VISIBLE); + mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable, + getNavBarShowDelay()); } else { + mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable); mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 42cfd39d7a2a4..78554525e720c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -55,12 +55,24 @@ public class StatusBarWindowView extends FrameLayout { @Override protected boolean fitSystemWindows(Rect insets) { if (getFitsSystemWindows()) { - setPadding(insets.left, insets.top, insets.right, 0); + boolean changed = insets.left != getPaddingLeft() + || insets.top != getPaddingTop() + || insets.right != getPaddingRight() + || insets.bottom != getPaddingBottom(); + if (changed) { + setPadding(insets.left, insets.top, insets.right, 0); + } insets.left = 0; insets.top = 0; insets.right = 0; } else { - setPadding(0, 0, 0, 0); + boolean changed = getPaddingLeft() != 0 + || getPaddingRight() != 0 + || getPaddingTop() != 0 + || getPaddingBottom() != 0; + if (changed) { + setPadding(0, 0, 0, 0); + } } return false; }