diff options
author | Jorim Jaggi <jjaggi@google.com> | 2015-05-07 11:41:41 -0700 |
---|---|---|
committer | Jorim Jaggi <jjaggi@google.com> | 2015-05-13 14:23:05 -0700 |
commit | 827e0facfefd0c0033dcfb1747b4fa6f80f9e0e2 (patch) | |
tree | c6905d367303ce8dc3ba3dde34d0b18c6314f29e /core/java/android/view/ViewRootImpl.java | |
parent | e1d0188b6954bd42160cbb1e9445e08c7c9c0ae3 (diff) | |
download | frameworks_base-827e0facfefd0c0033dcfb1747b4fa6f80f9e0e2.zip frameworks_base-827e0facfefd0c0033dcfb1747b4fa6f80f9e0e2.tar.gz frameworks_base-827e0facfefd0c0033dcfb1747b4fa6f80f9e0e2.tar.bz2 |
Make sure the app can draw a frame before unlocking
- The mechanism to stop windows drawing while window animator was
animating was somehow flaky. It relied on the fact that the client
would call relayout() whenever the animating state changed. This is
mostly the case, but not for lockscreen animations. Instead, we now
use a push model, where window manager tells the app that the state
has changed.
- In addition, it only stopped drawing if that window was animating,
but then only resumed drawing after all windows have finished
animating. Now, we do this per window, so we only stop drawing for
windows that are currently animating.
- We resume the top activity now at the very beginning of the
unlocking sequence. This gives the app a chance to draw a frame
before the user sees anything. If it's to slow, then we just use the
outdated framebuffer.
Bug: 19964562
Change-Id: Ifef8abd189a3146d854b81b9b948861e4d38c155
Diffstat (limited to 'core/java/android/view/ViewRootImpl.java')
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 79 |
1 files changed, 51 insertions, 28 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 57c6cbf..371d97b 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -220,6 +220,9 @@ public final class ViewRootImpl implements ViewParent, boolean mLastWasImTarget; boolean mWindowsAnimating; boolean mDrawDuringWindowsAnimating; + + /** How many frames the app is still allowed to draw when a window animation is happening. */ + private int mRemainingFrameCount; boolean mIsDrawing; int mLastSystemUiVisibility; int mClientWindowLayoutFlags; @@ -1569,10 +1572,6 @@ public final class ViewRootImpl implements ViewParent, } final int surfaceGenerationId = mSurface.getGenerationId(); relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); - if (!mDrawDuringWindowsAnimating && - (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0) { - mWindowsAnimating = true; - } if (DEBUG_LAYOUT) Log.v(TAG, "relayout: frame=" + frame.toShortString() + " overscan=" + mPendingOverscanInsets.toShortString() @@ -1996,14 +1995,11 @@ public final class ViewRootImpl implements ViewParent, + mView.findFocus()); } } - if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0) { - // The first time we relayout the window, if the system is - // doing window animations, we want to hold of on any future - // draws until the animation is done. - mWindowsAnimating = true; - } } else if (mWindowsAnimating) { - skipDraw = true; + if (mRemainingFrameCount <= 0) { + skipDraw = true; + } + mRemainingFrameCount--; } mFirst = false; @@ -2800,7 +2796,7 @@ public final class ViewRootImpl implements ViewParent, public void setDrawDuringWindowsAnimating(boolean value) { mDrawDuringWindowsAnimating = value; if (value) { - handleDispatchDoneAnimating(); + handleDispatchWindowAnimationStopped(); } } @@ -3152,11 +3148,12 @@ public final class ViewRootImpl implements ViewParent, private final static int MSG_UPDATE_CONFIGURATION = 18; private final static int MSG_PROCESS_INPUT_EVENTS = 19; private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 21; - private final static int MSG_DISPATCH_DONE_ANIMATING = 22; - private final static int MSG_INVALIDATE_WORLD = 23; - private final static int MSG_WINDOW_MOVED = 24; - private final static int MSG_SYNTHESIZE_INPUT_EVENT = 25; - private final static int MSG_DISPATCH_WINDOW_SHOWN = 26; + private final static int MSG_INVALIDATE_WORLD = 22; + private final static int MSG_WINDOW_MOVED = 23; + private final static int MSG_SYNTHESIZE_INPUT_EVENT = 24; + private final static int MSG_DISPATCH_WINDOW_SHOWN = 25; + private final static int MSG_DISPATCH_WINDOW_ANIMATION_STOPPED = 26; + private final static int MSG_DISPATCH_WINDOW_ANIMATION_STARTED = 27; final class ViewRootHandler extends Handler { @Override @@ -3200,8 +3197,10 @@ public final class ViewRootImpl implements ViewParent, return "MSG_PROCESS_INPUT_EVENTS"; case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: return "MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST"; - case MSG_DISPATCH_DONE_ANIMATING: - return "MSG_DISPATCH_DONE_ANIMATING"; + case MSG_DISPATCH_WINDOW_ANIMATION_STARTED: + return "MSG_DISPATCH_WINDOW_ANIMATION_STARTED"; + case MSG_DISPATCH_WINDOW_ANIMATION_STOPPED: + return "MSG_DISPATCH_WINDOW_ANIMATION_STOPPED"; case MSG_WINDOW_MOVED: return "MSG_WINDOW_MOVED"; case MSG_SYNTHESIZE_INPUT_EVENT: @@ -3421,8 +3420,12 @@ public final class ViewRootImpl implements ViewParent, case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: { setAccessibilityFocus(null, null); } break; - case MSG_DISPATCH_DONE_ANIMATING: { - handleDispatchDoneAnimating(); + case MSG_DISPATCH_WINDOW_ANIMATION_STARTED: { + int remainingFrameCount = msg.arg1; + handleDispatchWindowAnimationStarted(remainingFrameCount); + } break; + case MSG_DISPATCH_WINDOW_ANIMATION_STOPPED: { + handleDispatchWindowAnimationStopped(); } break; case MSG_INVALIDATE_WORLD: { if (mView != null) { @@ -4038,7 +4041,7 @@ public final class ViewRootImpl implements ViewParent, } else { // If delivering a new non-key event, make sure the window is // now allowed to start updating. - handleDispatchDoneAnimating(); + handleDispatchWindowAnimationStopped(); final int source = q.mEvent.getSource(); if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) { return processPointerEvent(q); @@ -4068,7 +4071,7 @@ public final class ViewRootImpl implements ViewParent, if (event.getAction() != KeyEvent.ACTION_UP) { // If delivering a new key event, make sure the window is // now allowed to start updating. - handleDispatchDoneAnimating(); + handleDispatchWindowAnimationStopped(); } // Deliver the key to the view hierarchy. @@ -5285,7 +5288,14 @@ public final class ViewRootImpl implements ViewParent, } } - public void handleDispatchDoneAnimating() { + public void handleDispatchWindowAnimationStarted(int remainingFrameCount) { + if (!mDrawDuringWindowsAnimating) { + mRemainingFrameCount = remainingFrameCount; + mWindowsAnimating = true; + } + } + + public void handleDispatchWindowAnimationStopped() { if (mWindowsAnimating) { mWindowsAnimating = false; if (!mDirty.isEmpty() || mIsAnimating || mFullRedrawNeeded) { @@ -6189,8 +6199,13 @@ public final class ViewRootImpl implements ViewParent, mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_SYSTEM_UI_VISIBILITY, args)); } - public void dispatchDoneAnimating() { - mHandler.sendEmptyMessage(MSG_DISPATCH_DONE_ANIMATING); + public void dispatchWindowAnimationStarted(int remainingFrameCount) { + mHandler.obtainMessage(MSG_DISPATCH_WINDOW_ANIMATION_STARTED, + remainingFrameCount, 0 /* unused */).sendToTarget(); + } + + public void dispatchWindowAnimationStopped() { + mHandler.sendEmptyMessage(MSG_DISPATCH_WINDOW_ANIMATION_STOPPED); } public void dispatchCheckFocus() { @@ -6713,10 +6728,18 @@ public final class ViewRootImpl implements ViewParent, } @Override - public void doneAnimating() { + public void onAnimationStarted(int remainingFrameCount) { + final ViewRootImpl viewAncestor = mViewAncestor.get(); + if (viewAncestor != null) { + viewAncestor.dispatchWindowAnimationStarted(remainingFrameCount); + } + } + + @Override + public void onAnimationStopped() { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { - viewAncestor.dispatchDoneAnimating(); + viewAncestor.dispatchWindowAnimationStopped(); } } |